Added icons logo
@ -1,7 +1,7 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.immich_mobile">
|
package="com.example.immich_mobile">
|
||||||
<application
|
<application
|
||||||
android:label="immich_mobile"
|
android:label="Immich"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
<activity
|
<activity
|
||||||
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 115 KiB |
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 20 KiB |
@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Immich Mobile</string>
|
<string>Immich</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
/// Build the Scroll Thumb and label using the current configuration
|
/// Build the Scroll Thumb and label using the current configuration
|
||||||
@ -166,7 +165,7 @@ class DraggableScrollbar extends StatefulWidget {
|
|||||||
}) {
|
}) {
|
||||||
final scrollThumb = CustomPaint(
|
final scrollThumb = CustomPaint(
|
||||||
key: scrollThumbKey,
|
key: scrollThumbKey,
|
||||||
foregroundPainter: ArrowCustomPainter(Colors.grey),
|
foregroundPainter: ArrowCustomPainter(Colors.white),
|
||||||
child: Material(
|
child: Material(
|
||||||
elevation: 4.0,
|
elevation: 4.0,
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -348,7 +347,7 @@ class _DraggableScrollbarState extends State<DraggableScrollbar> with TickerProv
|
|||||||
|
|
||||||
double get barMaxScrollExtent => context.size!.height - widget.heightScrollThumb;
|
double get barMaxScrollExtent => context.size!.height - widget.heightScrollThumb;
|
||||||
|
|
||||||
double get barMinScrollExtent => 0.0;
|
double get barMinScrollExtent => 0;
|
||||||
|
|
||||||
double get viewMaxScrollExtent => widget.controller.position.maxScrollExtent;
|
double get viewMaxScrollExtent => widget.controller.position.maxScrollExtent;
|
||||||
|
|
||||||
|
@ -105,8 +105,8 @@ class ImmichSliverAppBar extends ConsumerWidget {
|
|||||||
statusBarColor: Colors.indigo,
|
statusBarColor: Colors.indigo,
|
||||||
|
|
||||||
// Status bar brightness (optional)
|
// Status bar brightness (optional)
|
||||||
statusBarIconBrightness: Brightness.dark, // For Android (dark icons)
|
statusBarIconBrightness: Brightness.light, // For Android (dark icons)
|
||||||
statusBarBrightness: Brightness.light, // For iOS (dark icons)
|
statusBarBrightness: Brightness.dark,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,6 @@ import 'package:hive_flutter/hive_flutter.dart';
|
|||||||
import 'package:immich_mobile/constants/hive_box.dart';
|
import 'package:immich_mobile/constants/hive_box.dart';
|
||||||
import 'package:immich_mobile/shared/models/immich_asset.model.dart';
|
import 'package:immich_mobile/shared/models/immich_asset.model.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
import 'package:transparent_image/transparent_image.dart';
|
|
||||||
|
|
||||||
class ThumbnailImage extends StatelessWidget {
|
class ThumbnailImage extends StatelessWidget {
|
||||||
final ImmichAsset asset;
|
final ImmichAsset asset;
|
||||||
@ -17,7 +16,6 @@ class ThumbnailImage extends StatelessWidget {
|
|||||||
var box = Hive.box(userInfoBox);
|
var box = Hive.box(userInfoBox);
|
||||||
var thumbnailRequestUrl =
|
var thumbnailRequestUrl =
|
||||||
'${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true';
|
'${box.get(serverEndpointKey)}/asset/file?aid=${asset.deviceAssetId}&did=${asset.deviceId}&isThumb=true';
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
AutoRouter.of(context).push(
|
AutoRouter.of(context).push(
|
||||||
@ -44,7 +42,10 @@ class ThumbnailImage extends StatelessWidget {
|
|||||||
scale: 0.2,
|
scale: 0.2,
|
||||||
child: CircularProgressIndicator(value: downloadProgress.progress),
|
child: CircularProgressIndicator(value: downloadProgress.progress),
|
||||||
),
|
),
|
||||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
errorWidget: (context, url, error) {
|
||||||
|
debugPrint("Error Loading Thumbnail Widget $error");
|
||||||
|
return const Icon(Icons.error);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -84,6 +84,7 @@ class HomePage extends HookConsumerWidget {
|
|||||||
int? currentMonth = DateTime.tryParse(dateTitle)?.month;
|
int? currentMonth = DateTime.tryParse(dateTitle)?.month;
|
||||||
int? previousMonth = DateTime.tryParse(lastGroupDate)?.month;
|
int? previousMonth = DateTime.tryParse(lastGroupDate)?.month;
|
||||||
|
|
||||||
|
// Add Monthly Title Group if started at the beginning of the month
|
||||||
if ((currentMonth! - previousMonth!) != 0) {
|
if ((currentMonth! - previousMonth!) != 0) {
|
||||||
var monthTitleText = DateFormat('MMMM, y').format(DateTime.parse(dateTitle));
|
var monthTitleText = DateFormat('MMMM, y').format(DateTime.parse(dateTitle));
|
||||||
|
|
||||||
@ -92,10 +93,12 @@ class HomePage extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add Daily Title Group
|
||||||
imageGridGroup.add(
|
imageGridGroup.add(
|
||||||
_buildDateGroupTitle(dateTitle),
|
DailyTitleText(dateTitle: dateTitle),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add Image Group
|
||||||
imageGridGroup.add(
|
imageGridGroup.add(
|
||||||
ImageGrid(assetGroup: assetGroup),
|
ImageGrid(assetGroup: assetGroup),
|
||||||
);
|
);
|
||||||
@ -121,8 +124,9 @@ class HomePage extends HookConsumerWidget {
|
|||||||
// return Text(scrollLabelText.value);
|
// return Text(scrollLabelText.value);
|
||||||
// },
|
// },
|
||||||
// labelConstraints: const BoxConstraints.tightFor(width: 200.0, height: 30.0),
|
// labelConstraints: const BoxConstraints.tightFor(width: 200.0, height: 30.0),
|
||||||
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
heightScrollThumb: 40.0,
|
heightScrollThumb: 48.0,
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
@ -166,3 +170,41 @@ class MonthlyTitleText extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DailyTitleText extends StatelessWidget {
|
||||||
|
const DailyTitleText({
|
||||||
|
Key? key,
|
||||||
|
required this.dateTitle,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final String dateTitle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var currentYear = DateTime.now().year;
|
||||||
|
var groupYear = DateTime.parse(dateTitle).year;
|
||||||
|
var formatDateTemplate = currentYear == groupYear ? 'E, MMM dd' : 'E, MMM dd, yyyy';
|
||||||
|
var dateText = DateFormat(formatDateTemplate).format(DateTime.parse(dateTitle));
|
||||||
|
|
||||||
|
return SliverToBoxAdapter(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 24.0, bottom: 24.0, left: 3.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8.0, bottom: 5.0, top: 5.0),
|
||||||
|
child: Text(
|
||||||
|
dateText,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Colors.black87,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,7 +12,7 @@ class LoginForm extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final usernameController = useTextEditingController(text: 'testuser@email.com');
|
final usernameController = useTextEditingController(text: 'testuser@email.com');
|
||||||
final passwordController = useTextEditingController(text: 'password');
|
final passwordController = useTextEditingController(text: 'password');
|
||||||
final serverEndpointController = useTextEditingController(text: 'http://192.168.1.103:3000');
|
final serverEndpointController = useTextEditingController(text: 'http://192.168.1.216:3000');
|
||||||
|
|
||||||
return Center(
|
return Center(
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
|
@ -3,3 +3,6 @@ build:
|
|||||||
|
|
||||||
watch:
|
watch:
|
||||||
flutter packages pub run build_runner watch
|
flutter packages pub run build_runner watch
|
||||||
|
|
||||||
|
create_app_icon:
|
||||||
|
flutter pub run flutter_launcher_icons:main
|
@ -15,6 +15,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.2.0"
|
version: "3.2.0"
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.11"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -321,6 +328,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.2"
|
version: "0.18.2"
|
||||||
|
flutter_launcher_icons:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_launcher_icons
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.9.2"
|
||||||
flutter_lints:
|
flutter_lints:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@ -429,6 +443,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
|
image:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.1"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -478,6 +499,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.11"
|
version: "0.12.11"
|
||||||
|
material_color_utilities:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: material_color_utilities
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.3"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -576,6 +604,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.0"
|
version: "3.4.0"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.4.0"
|
||||||
photo_manager:
|
photo_manager:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -755,7 +790,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.3"
|
version: "0.4.8"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -840,6 +875,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.2.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.3.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -26,6 +26,7 @@ dependencies:
|
|||||||
exif: ^3.1.1
|
exif: ^3.1.1
|
||||||
transparent_image: ^2.0.0
|
transparent_image: ^2.0.0
|
||||||
visibility_detector: ^0.2.2
|
visibility_detector: ^0.2.2
|
||||||
|
flutter_launcher_icons: "^0.9.2"
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@ -39,3 +40,9 @@ flutter:
|
|||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
assets:
|
assets:
|
||||||
- assets/
|
- assets/
|
||||||
|
|
||||||
|
flutter_icons:
|
||||||
|
image_path_android: "assets/immich-logo-no-outline.png"
|
||||||
|
image_path_ios: "assets/immich-logo-no-outline.png"
|
||||||
|
android: true # can specify file name here e.g. "ic_launcher"
|
||||||
|
ios: true # can specify file name here e.g. "My-Launcher-Icon
|
||||||
|