mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 16:56:19 +01:00
Add a dialog that lead user to the video preview help page
This commit is contained in:
parent
bd0e4fd342
commit
4fc6b17de1
15 changed files with 180 additions and 27 deletions
|
@ -152,6 +152,12 @@ class PrefController {
|
||||||
value: value,
|
value: value,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Future<bool> setDontShowVideoPreviewHint(bool value) => _set<bool>(
|
||||||
|
controller: _isDontShowVideoPreviewHintController,
|
||||||
|
setter: (pref, value) => pref.setDontShowVideoPreviewHint(value),
|
||||||
|
value: value,
|
||||||
|
);
|
||||||
|
|
||||||
Future<bool> _set<T>({
|
Future<bool> _set<T>({
|
||||||
required BehaviorSubject<T> controller,
|
required BehaviorSubject<T> controller,
|
||||||
required Future<bool> Function(Pref pref, T value) setter,
|
required Future<bool> Function(Pref pref, T value) setter,
|
||||||
|
@ -249,6 +255,9 @@ class PrefController {
|
||||||
@NpSubjectAccessor(type: "Color?")
|
@NpSubjectAccessor(type: "Color?")
|
||||||
late final _secondarySeedColorController = BehaviorSubject<Color?>.seeded(
|
late final _secondarySeedColorController = BehaviorSubject<Color?>.seeded(
|
||||||
_c.pref.getSecondarySeedColor()?.run(Color.new));
|
_c.pref.getSecondarySeedColor()?.run(Color.new));
|
||||||
|
@npSubjectAccessor
|
||||||
|
late final _isDontShowVideoPreviewHintController =
|
||||||
|
BehaviorSubject.seeded(_c.pref.isDontShowVideoPreviewHintOr(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@npSubjectAccessor
|
@npSubjectAccessor
|
||||||
|
|
|
@ -148,6 +148,15 @@ extension $PrefControllerNpSubjectAccessor on PrefController {
|
||||||
Stream<Color?> get secondarySeedColorChange =>
|
Stream<Color?> get secondarySeedColorChange =>
|
||||||
secondarySeedColor.distinct().skip(1);
|
secondarySeedColor.distinct().skip(1);
|
||||||
Color? get secondarySeedColorValue => _secondarySeedColorController.value;
|
Color? get secondarySeedColorValue => _secondarySeedColorController.value;
|
||||||
|
// _isDontShowVideoPreviewHintController
|
||||||
|
ValueStream<bool> get isDontShowVideoPreviewHint =>
|
||||||
|
_isDontShowVideoPreviewHintController.stream;
|
||||||
|
Stream<bool> get isDontShowVideoPreviewHintNew =>
|
||||||
|
isDontShowVideoPreviewHint.skip(1);
|
||||||
|
Stream<bool> get isDontShowVideoPreviewHintChange =>
|
||||||
|
isDontShowVideoPreviewHint.distinct().skip(1);
|
||||||
|
bool get isDontShowVideoPreviewHintValue =>
|
||||||
|
_isDontShowVideoPreviewHintController.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension $SecurePrefControllerNpSubjectAccessor on SecurePrefController {
|
extension $SecurePrefControllerNpSubjectAccessor on SecurePrefController {
|
||||||
|
|
|
@ -81,4 +81,11 @@ extension on Pref {
|
||||||
return provider.setString(PrefKey.protectedPageAuthPassword, value);
|
return provider.setString(PrefKey.protectedPageAuthPassword, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool? isDontShowVideoPreviewHint() =>
|
||||||
|
provider.getBool(PrefKey.dontShowVideoPreviewHint);
|
||||||
|
bool isDontShowVideoPreviewHintOr(bool def) =>
|
||||||
|
isDontShowVideoPreviewHint() ?? def;
|
||||||
|
Future<bool> setDontShowVideoPreviewHint(bool value) =>
|
||||||
|
provider.setBool(PrefKey.dontShowVideoPreviewHint, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,7 @@ enum PrefKey implements PrefKeyInterface {
|
||||||
protectedPageAuthType,
|
protectedPageAuthType,
|
||||||
protectedPageAuthPin,
|
protectedPageAuthPin,
|
||||||
protectedPageAuthPassword,
|
protectedPageAuthPassword,
|
||||||
|
dontShowVideoPreviewHint,
|
||||||
;
|
;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -196,6 +197,8 @@ enum PrefKey implements PrefKeyInterface {
|
||||||
return "protectedPageAuthPin";
|
return "protectedPageAuthPin";
|
||||||
case PrefKey.protectedPageAuthPassword:
|
case PrefKey.protectedPageAuthPassword:
|
||||||
return "protectedPageAuthPassword";
|
return "protectedPageAuthPassword";
|
||||||
|
case PrefKey.dontShowVideoPreviewHint:
|
||||||
|
return "dontShowVideoPreviewHint";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,3 +13,4 @@ const enhanceRetouchUrl = "https://bit.ly/3Ds2cea";
|
||||||
const editPhotosUrl = "https://bit.ly/3v82oKA";
|
const editPhotosUrl = "https://bit.ly/3v82oKA";
|
||||||
const collectionTypesUrl = "https://bit.ly/3OwSiNq";
|
const collectionTypesUrl = "https://bit.ly/3OwSiNq";
|
||||||
const contributorsUrl = "https://bit.ly/3QhlQQs";
|
const contributorsUrl = "https://bit.ly/3QhlQQs";
|
||||||
|
const videoPreviewUrl = "https://bit.ly/4c7cazP";
|
||||||
|
|
|
@ -1485,6 +1485,8 @@
|
||||||
"description": "There's no HTTPS server in the account list"
|
"description": "There's no HTTPS server in the account list"
|
||||||
},
|
},
|
||||||
"trustedCertManagerFailedToRemoveCertError": "Failed to remove certificate",
|
"trustedCertManagerFailedToRemoveCertError": "Failed to remove certificate",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle": "Having trouble with video thumbnails?",
|
||||||
|
"dontShowAgain": "Don't show again",
|
||||||
|
|
||||||
"errorUnauthenticated": "Unauthenticated access. Please sign-in again if the problem continues",
|
"errorUnauthenticated": "Unauthenticated access. Please sign-in again if the problem continues",
|
||||||
"@errorUnauthenticated": {
|
"@errorUnauthenticated": {
|
||||||
|
|
|
@ -247,6 +247,8 @@
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError",
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain",
|
||||||
"errorUnauthenticated",
|
"errorUnauthenticated",
|
||||||
"errorDisconnected",
|
"errorDisconnected",
|
||||||
"errorLocked",
|
"errorLocked",
|
||||||
|
@ -280,7 +282,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
|
@ -332,7 +336,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"el": [
|
"el": [
|
||||||
|
@ -467,7 +473,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"es": [
|
"es": [
|
||||||
|
@ -493,7 +501,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fi": [
|
"fi": [
|
||||||
|
@ -519,7 +529,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fr": [
|
"fr": [
|
||||||
|
@ -545,7 +557,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
|
@ -576,7 +590,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nl": [
|
"nl": [
|
||||||
|
@ -944,6 +960,8 @@
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError",
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain",
|
||||||
"errorUnauthenticated",
|
"errorUnauthenticated",
|
||||||
"errorDisconnected",
|
"errorDisconnected",
|
||||||
"errorLocked",
|
"errorLocked",
|
||||||
|
@ -981,7 +999,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"pt": [
|
"pt": [
|
||||||
|
@ -1027,7 +1047,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ru": [
|
"ru": [
|
||||||
|
@ -1053,7 +1075,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
|
@ -1062,7 +1086,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
|
@ -1119,7 +1145,9 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh_Hant": [
|
"zh_Hant": [
|
||||||
|
@ -1270,6 +1298,8 @@
|
||||||
"trustedCertManagerAlreadyTrustedError",
|
"trustedCertManagerAlreadyTrustedError",
|
||||||
"trustedCertManagerSelectServer",
|
"trustedCertManagerSelectServer",
|
||||||
"trustedCertManagerNoHttpsServerError",
|
"trustedCertManagerNoHttpsServerError",
|
||||||
"trustedCertManagerFailedToRemoveCertError"
|
"trustedCertManagerFailedToRemoveCertError",
|
||||||
|
"missingVideoThumbnailHelpDialogTitle",
|
||||||
|
"dontShowAgain"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,7 @@ class SessionStorage {
|
||||||
|
|
||||||
DateTime lastSuspendTime = clock.now();
|
DateTime lastSuspendTime = clock.now();
|
||||||
|
|
||||||
|
bool hasShownVideoPreviewHint = false;
|
||||||
|
|
||||||
static final _inst = SessionStorage._();
|
static final _inst = SessionStorage._();
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ class _Bloc extends Bloc<_Event, _State>
|
||||||
on<_UpdateDateTimeGroup>(_onUpdateDateTimeGroup);
|
on<_UpdateDateTimeGroup>(_onUpdateDateTimeGroup);
|
||||||
on<_UpdateMemories>(_onUpdateMemories);
|
on<_UpdateMemories>(_onUpdateMemories);
|
||||||
|
|
||||||
|
on<_TripMissingVideoPreview>(_onTripMissingVideoPreview);
|
||||||
|
|
||||||
on<_SetError>(_onSetError);
|
on<_SetError>(_onSetError);
|
||||||
|
|
||||||
_subscriptions
|
_subscriptions
|
||||||
|
@ -486,6 +488,14 @@ class _Bloc extends Bloc<_Event, _State>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onTripMissingVideoPreview(
|
||||||
|
_TripMissingVideoPreview ev, Emitter<_State> emit) {
|
||||||
|
// _log.info(ev);
|
||||||
|
if (!state.hasMissingVideoPreview) {
|
||||||
|
emit(state.copyWith(hasMissingVideoPreview: true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _onSetError(_SetError ev, Emitter<_State> emit) {
|
void _onSetError(_SetError ev, Emitter<_State> emit) {
|
||||||
_log.info(ev);
|
_log.info(ev);
|
||||||
emit(state.copyWith(error: ExceptionEvent(ev.error, ev.stackTrace)));
|
emit(state.copyWith(error: ExceptionEvent(ev.error, ev.stackTrace)));
|
||||||
|
|
|
@ -25,6 +25,7 @@ class _State {
|
||||||
this.minimapItems,
|
this.minimapItems,
|
||||||
required this.minimapYRatio,
|
required this.minimapYRatio,
|
||||||
this.scrollDate,
|
this.scrollDate,
|
||||||
|
required this.hasMissingVideoPreview,
|
||||||
this.error,
|
this.error,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ class _State {
|
||||||
isScrolling: false,
|
isScrolling: false,
|
||||||
filesSummary: const DbFilesSummary(items: {}),
|
filesSummary: const DbFilesSummary(items: {}),
|
||||||
minimapYRatio: 1,
|
minimapYRatio: 1,
|
||||||
|
hasMissingVideoPreview: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -76,6 +78,8 @@ class _State {
|
||||||
final double minimapYRatio;
|
final double minimapYRatio;
|
||||||
final Date? scrollDate;
|
final Date? scrollDate;
|
||||||
|
|
||||||
|
final bool hasMissingVideoPreview;
|
||||||
|
|
||||||
final ExceptionEvent? error;
|
final ExceptionEvent? error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,6 +319,14 @@ class _UpdateMemories implements _Event {
|
||||||
String toString() => _$toString();
|
String toString() => _$toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@toString
|
||||||
|
class _TripMissingVideoPreview implements _Event {
|
||||||
|
const _TripMissingVideoPreview();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => _$toString();
|
||||||
|
}
|
||||||
|
|
||||||
@toString
|
@toString
|
||||||
class _SetError implements _Event {
|
class _SetError implements _Event {
|
||||||
const _SetError(this.error, [this.stackTrace]);
|
const _SetError(this.error, [this.stackTrace]);
|
||||||
|
|
|
@ -72,6 +72,9 @@ class _VideoItem extends _FileItem {
|
||||||
account: account,
|
account: account,
|
||||||
previewUrl: _previewUrl,
|
previewUrl: _previewUrl,
|
||||||
isFavorite: file.fdIsFavorite,
|
isFavorite: file.fdIsFavorite,
|
||||||
|
onError: () {
|
||||||
|
context.addEvent(const _TripMissingVideoPreview());
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -311,3 +311,30 @@ class _ScrollLabel extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _VideoPreviewHintDialog extends StatelessWidget {
|
||||||
|
const _VideoPreviewHintDialog();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(L10n.global().missingVideoThumbnailHelpDialogTitle),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
launch(help_util.videoPreviewUrl);
|
||||||
|
},
|
||||||
|
child: Text(L10n.global().learnMoreButtonLabel),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
context.read<PrefController>().setDontShowVideoPreviewHint(true);
|
||||||
|
},
|
||||||
|
child: Text(L10n.global().dontShowAgain),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,13 +33,16 @@ import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/event/event.dart';
|
import 'package:nc_photos/event/event.dart';
|
||||||
import 'package:nc_photos/exception_event.dart';
|
import 'package:nc_photos/exception_event.dart';
|
||||||
import 'package:nc_photos/flutter_util.dart' as flutter_util;
|
import 'package:nc_photos/flutter_util.dart' as flutter_util;
|
||||||
|
import 'package:nc_photos/help_utils.dart' as help_util;
|
||||||
import 'package:nc_photos/k.dart' as k;
|
import 'package:nc_photos/k.dart' as k;
|
||||||
import 'package:nc_photos/progress_util.dart';
|
import 'package:nc_photos/progress_util.dart';
|
||||||
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
import 'package:nc_photos/remote_storage_util.dart' as remote_storage_util;
|
||||||
|
import 'package:nc_photos/session_storage.dart';
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/stream_extension.dart';
|
import 'package:nc_photos/stream_extension.dart';
|
||||||
import 'package:nc_photos/theme.dart';
|
import 'package:nc_photos/theme.dart';
|
||||||
import 'package:nc_photos/theme/dimension.dart';
|
import 'package:nc_photos/theme/dimension.dart';
|
||||||
|
import 'package:nc_photos/url_launcher_util.dart';
|
||||||
import 'package:nc_photos/widget/collection_browser.dart';
|
import 'package:nc_photos/widget/collection_browser.dart';
|
||||||
import 'package:nc_photos/widget/collection_picker.dart';
|
import 'package:nc_photos/widget/collection_picker.dart';
|
||||||
import 'package:nc_photos/widget/file_sharer_dialog.dart';
|
import 'package:nc_photos/widget/file_sharer_dialog.dart';
|
||||||
|
@ -133,6 +136,23 @@ class _WrappedHomePhotosState extends State<_WrappedHomePhotos> {
|
||||||
},
|
},
|
||||||
child: MultiBlocListener(
|
child: MultiBlocListener(
|
||||||
listeners: [
|
listeners: [
|
||||||
|
_BlocListenerT<bool>(
|
||||||
|
selector: (state) => state.hasMissingVideoPreview,
|
||||||
|
listener: (context, hasMissingVideoPreview) {
|
||||||
|
if (hasMissingVideoPreview) {
|
||||||
|
if (!context
|
||||||
|
.read<PrefController>()
|
||||||
|
.isDontShowVideoPreviewHintValue &&
|
||||||
|
!SessionStorage().hasShownVideoPreviewHint) {
|
||||||
|
SessionStorage().hasShownVideoPreviewHint = true;
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => const _VideoPreviewHintDialog(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
_BlocListenerT<ExceptionEvent?>(
|
_BlocListenerT<ExceptionEvent?>(
|
||||||
selector: (state) => state.error,
|
selector: (state) => state.error,
|
||||||
listener: (context, error) {
|
listener: (context, error) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ abstract class $_StateCopyWithWorker {
|
||||||
List<_MinimapItem>? minimapItems,
|
List<_MinimapItem>? minimapItems,
|
||||||
double? minimapYRatio,
|
double? minimapYRatio,
|
||||||
Date? scrollDate,
|
Date? scrollDate,
|
||||||
|
bool? hasMissingVideoPreview,
|
||||||
ExceptionEvent? error});
|
ExceptionEvent? error});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +65,7 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
|
||||||
dynamic minimapItems = copyWithNull,
|
dynamic minimapItems = copyWithNull,
|
||||||
dynamic minimapYRatio,
|
dynamic minimapYRatio,
|
||||||
dynamic scrollDate = copyWithNull,
|
dynamic scrollDate = copyWithNull,
|
||||||
|
dynamic hasMissingVideoPreview,
|
||||||
dynamic error = copyWithNull}) {
|
dynamic error = copyWithNull}) {
|
||||||
return _State(
|
return _State(
|
||||||
files: files as List<FileDescriptor>? ?? that.files,
|
files: files as List<FileDescriptor>? ?? that.files,
|
||||||
|
@ -102,6 +104,8 @@ class _$_StateCopyWithWorkerImpl implements $_StateCopyWithWorker {
|
||||||
minimapYRatio: minimapYRatio as double? ?? that.minimapYRatio,
|
minimapYRatio: minimapYRatio as double? ?? that.minimapYRatio,
|
||||||
scrollDate:
|
scrollDate:
|
||||||
scrollDate == copyWithNull ? that.scrollDate : scrollDate as Date?,
|
scrollDate == copyWithNull ? that.scrollDate : scrollDate as Date?,
|
||||||
|
hasMissingVideoPreview:
|
||||||
|
hasMissingVideoPreview as bool? ?? that.hasMissingVideoPreview,
|
||||||
error: error == copyWithNull ? that.error : error as ExceptionEvent?);
|
error: error == copyWithNull ? that.error : error as ExceptionEvent?);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +184,7 @@ extension _$_ContentListBodyNpLog on _ContentListBody {
|
||||||
extension _$_StateToString on _State {
|
extension _$_StateToString on _State {
|
||||||
String _$toString() {
|
String _$toString() {
|
||||||
// ignore: unnecessary_string_interpolations
|
// ignore: unnecessary_string_interpolations
|
||||||
return "_State {files: [length: ${files.length}], isLoading: $isLoading, transformedItems: [length: ${transformedItems.length}], selectedItems: {length: ${selectedItems.length}}, filesSummary: $filesSummary, visibleDates: {length: ${visibleDates.length}}, queriedDates: {length: ${queriedDates.length}}, isEnableMemoryCollection: $isEnableMemoryCollection, memoryCollections: [length: ${memoryCollections.length}], contentListMaxExtent: ${contentListMaxExtent == null ? null : "${contentListMaxExtent!.toStringAsFixed(3)}"}, syncProgress: $syncProgress, zoom: $zoom, scale: ${scale == null ? null : "${scale!.toStringAsFixed(3)}"}, viewWidth: ${viewWidth == null ? null : "${viewWidth!.toStringAsFixed(3)}"}, viewHeight: ${viewHeight == null ? null : "${viewHeight!.toStringAsFixed(3)}"}, itemPerRow: $itemPerRow, itemSize: ${itemSize == null ? null : "${itemSize!.toStringAsFixed(3)}"}, isScrolling: $isScrolling, minimapItems: ${minimapItems == null ? null : "[length: ${minimapItems!.length}]"}, minimapYRatio: ${minimapYRatio.toStringAsFixed(3)}, scrollDate: $scrollDate, error: $error}";
|
return "_State {files: [length: ${files.length}], isLoading: $isLoading, transformedItems: [length: ${transformedItems.length}], selectedItems: {length: ${selectedItems.length}}, filesSummary: $filesSummary, visibleDates: {length: ${visibleDates.length}}, queriedDates: {length: ${queriedDates.length}}, isEnableMemoryCollection: $isEnableMemoryCollection, memoryCollections: [length: ${memoryCollections.length}], contentListMaxExtent: ${contentListMaxExtent == null ? null : "${contentListMaxExtent!.toStringAsFixed(3)}"}, syncProgress: $syncProgress, zoom: $zoom, scale: ${scale == null ? null : "${scale!.toStringAsFixed(3)}"}, viewWidth: ${viewWidth == null ? null : "${viewWidth!.toStringAsFixed(3)}"}, viewHeight: ${viewHeight == null ? null : "${viewHeight!.toStringAsFixed(3)}"}, itemPerRow: $itemPerRow, itemSize: ${itemSize == null ? null : "${itemSize!.toStringAsFixed(3)}"}, isScrolling: $isScrolling, minimapItems: ${minimapItems == null ? null : "[length: ${minimapItems!.length}]"}, minimapYRatio: ${minimapYRatio.toStringAsFixed(3)}, scrollDate: $scrollDate, hasMissingVideoPreview: $hasMissingVideoPreview, error: $error}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,6 +364,13 @@ extension _$_UpdateMemoriesToString on _UpdateMemories {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension _$_TripMissingVideoPreviewToString on _TripMissingVideoPreview {
|
||||||
|
String _$toString() {
|
||||||
|
// ignore: unnecessary_string_interpolations
|
||||||
|
return "_TripMissingVideoPreview {}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension _$_SetErrorToString on _SetError {
|
extension _$_SetErrorToString on _SetError {
|
||||||
String _$toString() {
|
String _$toString() {
|
||||||
// ignore: unnecessary_string_interpolations
|
// ignore: unnecessary_string_interpolations
|
||||||
|
|
|
@ -278,6 +278,7 @@ class PhotoListVideo extends StatelessWidget {
|
||||||
required this.account,
|
required this.account,
|
||||||
required this.previewUrl,
|
required this.previewUrl,
|
||||||
this.isFavorite = false,
|
this.isFavorite = false,
|
||||||
|
this.onError,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -293,24 +294,29 @@ class PhotoListVideo extends StatelessWidget {
|
||||||
child: NetworkRectThumbnail(
|
child: NetworkRectThumbnail(
|
||||||
account: account,
|
account: account,
|
||||||
imageUrl: previewUrl,
|
imageUrl: previewUrl,
|
||||||
errorBuilder: (_) => Padding(
|
errorBuilder: (context) {
|
||||||
padding: const EdgeInsets.all(12),
|
onError?.call();
|
||||||
child: Icon(
|
return Padding(
|
||||||
Icons.image_not_supported,
|
padding: const EdgeInsets.all(12),
|
||||||
color: Theme.of(context).listPlaceholderForegroundColor,
|
child: Icon(
|
||||||
),
|
Icons.image_not_supported,
|
||||||
),
|
color: Theme.of(context).listPlaceholderForegroundColor,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Positioned.directional(
|
||||||
alignment: AlignmentDirectional.topEnd,
|
textDirection: Directionality.of(context),
|
||||||
padding: const EdgeInsets.all(6),
|
top: 6,
|
||||||
|
end: 6,
|
||||||
child: const Icon(Icons.play_circle_outlined, size: 17),
|
child: const Icon(Icons.play_circle_outlined, size: 17),
|
||||||
),
|
),
|
||||||
if (isFavorite)
|
if (isFavorite)
|
||||||
Container(
|
Positioned.directional(
|
||||||
alignment: AlignmentDirectional.bottomStart,
|
textDirection: Directionality.of(context),
|
||||||
padding: const EdgeInsets.all(6),
|
bottom: 6,
|
||||||
|
start: 6,
|
||||||
child: const Icon(Icons.star, size: 15),
|
child: const Icon(Icons.star, size: 15),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -322,6 +328,7 @@ class PhotoListVideo extends StatelessWidget {
|
||||||
final Account account;
|
final Account account;
|
||||||
final String previewUrl;
|
final String previewUrl;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
|
final VoidCallback? onError;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PhotoListLabel extends StatelessWidget {
|
class PhotoListLabel extends StatelessWidget {
|
||||||
|
|
Loading…
Reference in a new issue