Merge branch 'update-dependency-v46' into dev

This commit is contained in:
Ming Ming 2022-07-09 22:20:50 +08:00
commit b65e8fdb91
47 changed files with 572 additions and 486 deletions

View file

@ -1 +1,8 @@
include: package:flutter_lints/flutter.yaml
linter:
rules:
depend_on_referenced_packages: false
prefer_interpolation_to_compose_strings: false
no_leading_underscores_for_local_identifiers: false
use_build_context_synchronously: false

View file

@ -31,10 +31,10 @@ class Response {
class Api {
Api(this._account);
_Files files() => _Files(this);
_Ocs ocs() => _Ocs(this);
_Systemtags systemtags() => _Systemtags(this);
_SystemtagsRelations systemtagsRelations() => _SystemtagsRelations(this);
ApiFiles files() => ApiFiles(this);
ApiOcs ocs() => ApiOcs(this);
ApiSystemtags systemtags() => ApiSystemtags(this);
ApiSystemtagsRelations systemtagsRelations() => ApiSystemtagsRelations(this);
static String getAuthorizationHeaderValue(Account account) {
final auth =
@ -108,8 +108,8 @@ class Api {
bool _isHttpStatusGood(int status) => status ~/ 100 == 2;
class _Files {
_Files(this._api);
class ApiFiles {
ApiFiles(this._api);
final Api _api;
@ -447,26 +447,26 @@ class _Files {
static final _log = Logger("api.api._Files");
}
class _Ocs {
_Ocs(this._api);
class ApiOcs {
ApiOcs(this._api);
_OcsDav dav() => _OcsDav(this);
_OcsFacerecognition facerecognition() => _OcsFacerecognition(this);
_OcsFilesSharing filesSharing() => _OcsFilesSharing(this);
ApiOcsDav dav() => ApiOcsDav(this);
ApiOcsFacerecognition facerecognition() => ApiOcsFacerecognition(this);
ApiOcsFilesSharing filesSharing() => ApiOcsFilesSharing(this);
final Api _api;
}
class _OcsDav {
_OcsDav(this._ocs);
class ApiOcsDav {
ApiOcsDav(this._ocs);
_OcsDavDirect direct() => _OcsDavDirect(this);
ApiOcsDavDirect direct() => ApiOcsDavDirect(this);
final _Ocs _ocs;
final ApiOcs _ocs;
}
class _OcsDavDirect {
_OcsDavDirect(this._dav);
class ApiOcsDavDirect {
ApiOcsDavDirect(this._dav);
Future<Response> post({
required int fileId,
@ -490,23 +490,23 @@ class _OcsDavDirect {
}
}
final _OcsDav _dav;
final ApiOcsDav _dav;
static final _log = Logger("api.api._OcsDavDirect");
}
class _OcsFacerecognition {
_OcsFacerecognition(this._ocs);
class ApiOcsFacerecognition {
ApiOcsFacerecognition(this._ocs);
_OcsFacerecognitionPersons persons() => _OcsFacerecognitionPersons(this);
_OcsFacerecognitionPerson person(String name) =>
_OcsFacerecognitionPerson(this, name);
ApiOcsFacerecognitionPersons persons() => ApiOcsFacerecognitionPersons(this);
ApiOcsFacerecognitionPerson person(String name) =>
ApiOcsFacerecognitionPerson(this, name);
final _Ocs _ocs;
final ApiOcs _ocs;
}
class _OcsFacerecognitionPersons {
_OcsFacerecognitionPersons(this._facerecognition);
class ApiOcsFacerecognitionPersons {
ApiOcsFacerecognitionPersons(this._facerecognition);
Future<Response> get() async {
try {
@ -526,23 +526,23 @@ class _OcsFacerecognitionPersons {
}
}
final _OcsFacerecognition _facerecognition;
final ApiOcsFacerecognition _facerecognition;
static final _log = Logger("api.api._OcsFacerecognitionPersons");
}
class _OcsFacerecognitionPerson {
_OcsFacerecognitionPerson(this._facerecognition, this._name);
class ApiOcsFacerecognitionPerson {
ApiOcsFacerecognitionPerson(this._facerecognition, this._name);
_OcsFacerecognitionPersonFaces faces() =>
_OcsFacerecognitionPersonFaces(this);
ApiOcsFacerecognitionPersonFaces faces() =>
ApiOcsFacerecognitionPersonFaces(this);
final _OcsFacerecognition _facerecognition;
final ApiOcsFacerecognition _facerecognition;
final String _name;
}
class _OcsFacerecognitionPersonFaces {
_OcsFacerecognitionPersonFaces(this._person);
class ApiOcsFacerecognitionPersonFaces {
ApiOcsFacerecognitionPersonFaces(this._person);
Future<Response> get() async {
try {
@ -562,24 +562,24 @@ class _OcsFacerecognitionPersonFaces {
}
}
final _OcsFacerecognitionPerson _person;
final ApiOcsFacerecognitionPerson _person;
static final _log = Logger("api.api._OcsFacerecognitionPersonFaces");
}
class _OcsFilesSharing {
_OcsFilesSharing(this._ocs);
class ApiOcsFilesSharing {
ApiOcsFilesSharing(this._ocs);
_OcsFilesSharingShares shares() => _OcsFilesSharingShares(this);
_OcsFilesSharingShare share(String shareId) =>
_OcsFilesSharingShare(this, shareId);
_OcsFilesSharingSharees sharees() => _OcsFilesSharingSharees(this);
ApiOcsFilesSharingShares shares() => ApiOcsFilesSharingShares(this);
ApiOcsFilesSharingShare share(String shareId) =>
ApiOcsFilesSharingShare(this, shareId);
ApiOcsFilesSharingSharees sharees() => ApiOcsFilesSharingSharees(this);
final _Ocs _ocs;
final ApiOcs _ocs;
}
class _OcsFilesSharingShares {
_OcsFilesSharingShares(this._filesSharing);
class ApiOcsFilesSharingShares {
ApiOcsFilesSharingShares(this._filesSharing);
/// Get Shares from a specific file or folder
///
@ -652,19 +652,19 @@ class _OcsFilesSharingShares {
}
}
final _OcsFilesSharing _filesSharing;
final ApiOcsFilesSharing _filesSharing;
static final _log = Logger("api.api._OcsFilesSharingShares");
}
class _OcsFilesSharingShare {
_OcsFilesSharingShare(this._filesSharing, this._shareId);
class ApiOcsFilesSharingShare {
ApiOcsFilesSharingShare(this._filesSharing, this._shareId);
/// Remove the given share
///
/// See: https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#delete-share
/// * The type of share ID is listed as int in the document, however, the
/// share ID returned in [_OcsFilesSharingShares.get] is actually a string. To
/// share ID returned in [ApiOcsFilesSharingShares.get] is actually a string. To
/// keep it consistent, we'll use string instead
Future<Response> delete() async {
try {
@ -681,14 +681,14 @@ class _OcsFilesSharingShare {
}
}
final _OcsFilesSharing _filesSharing;
final ApiOcsFilesSharing _filesSharing;
final String _shareId;
static final _log = Logger("api.api._OcsFilesSharingShare");
}
class _OcsFilesSharingSharees {
_OcsFilesSharingSharees(this._filesSharing);
class ApiOcsFilesSharingSharees {
ApiOcsFilesSharingSharees(this._filesSharing);
/// Get all sharees matching a search term
///
@ -720,13 +720,13 @@ class _OcsFilesSharingSharees {
}
}
final _OcsFilesSharing _filesSharing;
final ApiOcsFilesSharing _filesSharing;
static final _log = Logger("api.api._OcsFilesSharingSharees");
}
class _Systemtags {
const _Systemtags(this.api);
class ApiSystemtags {
const ApiSystemtags(this.api);
Future<Response> propfind({
id,
@ -791,17 +791,17 @@ class _Systemtags {
static final _log = Logger("api.api._Systemtags");
}
class _SystemtagsRelations {
const _SystemtagsRelations(this.api);
class ApiSystemtagsRelations {
const ApiSystemtagsRelations(this.api);
_SystemtagsRelationsFiles files(int fileId) =>
_SystemtagsRelationsFiles(this, fileId);
ApiSystemtagsRelationsFiles files(int fileId) =>
ApiSystemtagsRelationsFiles(this, fileId);
final Api api;
}
class _SystemtagsRelationsFiles {
const _SystemtagsRelationsFiles(this.systemtagsRelations, this.fileId);
class ApiSystemtagsRelationsFiles {
const ApiSystemtagsRelationsFiles(this.systemtagsRelations, this.fileId);
/// List systemtags associated with a file
///
@ -864,7 +864,7 @@ class _SystemtagsRelationsFiles {
}
}
final _SystemtagsRelations systemtagsRelations;
final ApiSystemtagsRelations systemtagsRelations;
final int fileId;
static final _log = Logger("api.api._SystemtagsRelationsFiles");

View file

@ -1,7 +1,6 @@
import 'package:equatable/equatable.dart';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/app_db.dart';
@ -46,7 +45,6 @@ Future<void> initAppLaunch() async {
await _initPref();
await _initAccountPrefs();
await _initDeviceInfo();
_initBloc();
_initEquatable();
if (features.isSupportSelfSignedCert) {
_initSelfSignedCertManager();
@ -135,10 +133,6 @@ Future<void> _initDeviceInfo() async {
}
}
void _initBloc() {
Bloc.observer = _BlocObserver();
}
void _initKiwi() {
final kiwi = KiwiContainer();
kiwi.registerInstance<EventBus>(EventBus());
@ -180,13 +174,3 @@ void _initVisibilityDetector() {
final _log = Logger("app_init");
var _hasInitedInThisIsolate = false;
class _BlocObserver extends BlocObserver {
@override
onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
_log.finer("${bloc.runtimeType} $change");
}
static final _log = Logger("app_init._BlocObserver");
}

View file

@ -55,20 +55,22 @@ class AlbumSearchBlocSuccess extends AlbumSearchBlocState {
}
class AlbumSearchBloc extends Bloc<AlbumSearchBlocEvent, AlbumSearchBlocState> {
AlbumSearchBloc() : super(const AlbumSearchBlocInit());
AlbumSearchBloc() : super(const AlbumSearchBlocInit()) {
on<AlbumSearchBlocEvent>(_onEvent);
}
@override
mapEventToState(AlbumSearchBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
AlbumSearchBlocEvent event, Emitter<AlbumSearchBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is AlbumSearchBlocSearchEvent) {
yield* _onEventSearch(event);
await _onEventSearch(event, emit);
} else if (event is AlbumSearchBlocUpdateItemsEvent) {
yield* _onEventUpdateItems(event);
await _onEventUpdateItems(event, emit);
}
}
Stream<AlbumSearchBlocState> _onEventSearch(
AlbumSearchBlocSearchEvent ev) async* {
Future<void> _onEventSearch(
AlbumSearchBlocSearchEvent ev, Emitter<AlbumSearchBlocState> emit) async {
final matches = _albums
.where((element) =>
element.name.toLowerCase().contains(ev.phrase.toLowerCase()))
@ -82,16 +84,16 @@ class AlbumSearchBloc extends Bloc<AlbumSearchBlocEvent, AlbumSearchBlocState> {
return a.name.compareTo(b.name);
}
});
yield AlbumSearchBlocSuccess(matches);
emit(AlbumSearchBlocSuccess(matches));
_lastSearch = ev;
}
Stream<AlbumSearchBlocState> _onEventUpdateItems(
AlbumSearchBlocUpdateItemsEvent ev) async* {
Future<void> _onEventUpdateItems(AlbumSearchBlocUpdateItemsEvent ev,
Emitter<AlbumSearchBlocState> emit) async {
_albums = ev.albums;
if (_lastSearch != null) {
// search again
yield* _onEventSearch(_lastSearch!);
await _onEventSearch(_lastSearch!, emit);
}
}

View file

@ -60,27 +60,30 @@ class AppPasswordExchangeBlocFailure extends AppPasswordExchangeBlocState {
class AppPasswordExchangeBloc
extends Bloc<AppPasswordExchangeBlocEvent, AppPasswordExchangeBlocState> {
AppPasswordExchangeBloc() : super(const AppPasswordExchangeBlocInit());
AppPasswordExchangeBloc() : super(const AppPasswordExchangeBlocInit()) {
on<AppPasswordExchangeBlocEvent>(_onEvent);
}
@override
mapEventToState(AppPasswordExchangeBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(AppPasswordExchangeBlocEvent event,
Emitter<AppPasswordExchangeBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is AppPasswordExchangeBlocConnect) {
yield* _exchangePassword(event.account);
await _onEventConnect(event, emit);
}
}
Stream<AppPasswordExchangeBlocState> _exchangePassword(
Account account) async* {
Future<void> _onEventConnect(AppPasswordExchangeBlocConnect ev,
Emitter<AppPasswordExchangeBlocState> emit) async {
final account = ev.account;
try {
final appPwd = await api_util.exchangePassword(account);
yield AppPasswordExchangeBlocSuccess(appPwd);
emit(AppPasswordExchangeBlocSuccess(appPwd));
} on InvalidBaseUrlException catch (e) {
_log.warning("[_exchangePassword] Invalid base url");
yield AppPasswordExchangeBlocFailure(e);
emit(AppPasswordExchangeBlocFailure(e));
} on HandshakeException catch (e) {
_log.info("[_exchangePassword] Self-signed cert");
yield AppPasswordExchangeBlocFailure(e);
emit(AppPasswordExchangeBlocFailure(e));
} catch (e, stacktrace) {
if (e is ApiException && e.response.statusCode == 401) {
// wrong password, normal
@ -90,7 +93,7 @@ class AppPasswordExchangeBloc
_log.shout("[_exchangePassword] Failed while exchanging password", e,
stacktrace);
}
yield AppPasswordExchangeBlocFailure(e);
emit(AppPasswordExchangeBlocFailure(e));
}
}

View file

@ -137,6 +137,8 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
},
logTag: "ListAlbumBloc.refresh",
);
on<ListAlbumBlocEvent>(_onEvent);
}
static bool require(DiContainer c) => true;
@ -160,16 +162,6 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
}
}
@override
mapEventToState(ListAlbumBlocEvent event) async* {
_log.info("[mapEventToState] $event");
if (event is ListAlbumBlocQuery) {
yield* _onEventQuery(event);
} else if (event is _ListAlbumBlocExternalEvent) {
yield* _onExternalEvent(event);
}
}
@override
close() {
_albumUpdatedListener.end();
@ -182,31 +174,42 @@ class ListAlbumBloc extends Bloc<ListAlbumBlocEvent, ListAlbumBlocState> {
return super.close();
}
Stream<ListAlbumBlocState> _onEventQuery(ListAlbumBlocQuery ev) async* {
yield ListAlbumBlocLoading(ev.account, state.items);
Future<void> _onEvent(
ListAlbumBlocEvent event, Emitter<ListAlbumBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListAlbumBlocQuery) {
await _onEventQuery(event, emit);
} else if (event is _ListAlbumBlocExternalEvent) {
await _onExternalEvent(event, emit);
}
}
Future<void> _onEventQuery(
ListAlbumBlocQuery ev, Emitter<ListAlbumBlocState> emit) async {
emit(ListAlbumBlocLoading(ev.account, state.items));
bool hasContent = state.items.isNotEmpty;
if (!hasContent) {
// show something instantly on first load
final cacheState = await _queryOffline(ev);
yield ListAlbumBlocLoading(ev.account, cacheState.items);
emit(ListAlbumBlocLoading(ev.account, cacheState.items));
hasContent = cacheState.items.isNotEmpty;
}
final newState = await _queryOnline(ev);
if (newState is ListAlbumBlocFailure) {
yield ListAlbumBlocFailure(
emit(ListAlbumBlocFailure(
ev.account,
newState.items.isNotEmpty ? newState.items : state.items,
newState.exception);
newState.exception));
} else {
yield newState;
emit(newState);
}
}
Stream<ListAlbumBlocState> _onExternalEvent(
_ListAlbumBlocExternalEvent ev) async* {
yield ListAlbumBlocInconsistent(state.account, state.items);
Future<void> _onExternalEvent(
_ListAlbumBlocExternalEvent ev, Emitter<ListAlbumBlocState> emit) async {
emit(ListAlbumBlocInconsistent(state.account, state.items));
}
void _onAlbumUpdatedEvent(AlbumUpdatedEvent ev) {

View file

@ -180,23 +180,25 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
ListAlbumShareOutlierBloc(this._c)
: assert(require(_c)),
assert(ListShare.require(_c)),
super(ListAlbumShareOutlierBlocInit());
super(ListAlbumShareOutlierBlocInit()) {
on<ListAlbumShareOutlierBlocEvent>(_onEvent);
}
static bool require(DiContainer c) => DiContainer.has(c, DiType.shareeRepo);
@override
mapEventToState(ListAlbumShareOutlierBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(ListAlbumShareOutlierBlocEvent event,
Emitter<ListAlbumShareOutlierBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListAlbumShareOutlierBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListAlbumShareOutlierBlocState> _onEventQuery(
ListAlbumShareOutlierBlocQuery ev) async* {
Future<void> _onEventQuery(ListAlbumShareOutlierBlocQuery ev,
Emitter<ListAlbumShareOutlierBlocState> emit) async {
try {
assert(ev.album.provider is AlbumStaticProvider);
yield ListAlbumShareOutlierBlocLoading(ev.account, state.items);
emit(ListAlbumShareOutlierBlocLoading(ev.account, state.items));
final albumShares = await () async {
var temp = (ev.album.shares ?? [])
@ -222,14 +224,14 @@ class ListAlbumShareOutlierBloc extends Bloc<ListAlbumShareOutlierBlocEvent,
await _processAlbumItems(ev.account, ev.album, albumShares, errors));
if (errors.isEmpty) {
yield ListAlbumShareOutlierBlocSuccess(ev.account, products);
emit(ListAlbumShareOutlierBlocSuccess(ev.account, products));
} else {
yield ListAlbumShareOutlierBlocFailure(
ev.account, products, errors.first);
emit(ListAlbumShareOutlierBlocFailure(
ev.account, products, errors.first));
}
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListAlbumShareOutlierBlocFailure(ev.account, state.items, e);
emit(ListAlbumShareOutlierBlocFailure(ev.account, state.items, e));
}
}

View file

@ -70,23 +70,26 @@ class ListFaceBlocFailure extends ListFaceBlocState {
/// List all people recognized in an account
class ListFaceBloc extends Bloc<ListFaceBlocEvent, ListFaceBlocState> {
ListFaceBloc() : super(ListFaceBlocInit());
ListFaceBloc() : super(ListFaceBlocInit()) {
on<ListFaceBlocEvent>(_onEvent);
}
@override
mapEventToState(ListFaceBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListFaceBlocEvent event, Emitter<ListFaceBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListFaceBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListFaceBlocState> _onEventQuery(ListFaceBlocQuery ev) async* {
Future<void> _onEventQuery(
ListFaceBlocQuery ev, Emitter<ListFaceBlocState> emit) async {
try {
yield ListFaceBlocLoading(ev.account, state.items);
yield ListFaceBlocSuccess(ev.account, await _query(ev));
emit(ListFaceBlocLoading(ev.account, state.items));
emit(ListFaceBlocSuccess(ev.account, await _query(ev)));
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListFaceBlocFailure(ev.account, state.items, e);
emit(ListFaceBlocFailure(ev.account, state.items, e));
}
}

View file

@ -71,7 +71,9 @@ class ListFavoriteBloc
ListFavoriteBloc(this._c)
: assert(require(_c)),
assert(ListFavorite.require(_c)),
super(const ListFavoriteBlocInit());
super(const ListFavoriteBlocInit()) {
on<ListFavoriteBlocEvent>(_onEvent);
}
static bool require(DiContainer c) => true;
@ -90,24 +92,25 @@ class ListFavoriteBloc
}
}
@override
mapEventToState(ListFavoriteBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListFavoriteBlocEvent event, Emitter<ListFavoriteBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListFavoriteBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListFavoriteBlocState> _onEventQuery(ListFavoriteBlocQuery ev) async* {
Future<void> _onEventQuery(
ListFavoriteBlocQuery ev, Emitter<ListFavoriteBlocState> emit) async {
List<File>? cache;
try {
yield ListFavoriteBlocLoading(ev.account, state.items);
emit(ListFavoriteBlocLoading(ev.account, state.items));
cache = await _queryOffline(ev);
if (cache != null) {
yield ListFavoriteBlocLoading(ev.account, cache);
emit(ListFavoriteBlocLoading(ev.account, cache));
}
final remote = await _queryOnline(ev);
yield ListFavoriteBlocSuccess(ev.account, remote);
emit(ListFavoriteBlocSuccess(ev.account, remote));
if (cache != null) {
CacheFavorite(_c)(ev.account, remote, cache: cache)
@ -118,7 +121,7 @@ class ListFavoriteBloc
}
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListFavoriteBlocFailure(ev.account, cache ?? state.items, e);
emit(ListFavoriteBlocFailure(ev.account, cache ?? state.items, e));
}
}

View file

@ -89,21 +89,23 @@ class ListImportableAlbumBloc
ListImportableAlbumBloc(this._c)
: assert(require(_c)),
assert(ListAlbum.require(_c)),
super(ListImportableAlbumBlocInit());
super(ListImportableAlbumBlocInit()) {
on<ListImportableAlbumBlocEvent>(_onEvent);
}
static bool require(DiContainer c) => DiContainer.has(c, DiType.fileRepo);
@override
mapEventToState(ListImportableAlbumBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(ListImportableAlbumBlocEvent event,
Emitter<ListImportableAlbumBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListImportableAlbumBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListImportableAlbumBlocState> _onEventQuery(
ListImportableAlbumBlocQuery ev) async* {
yield const ListImportableAlbumBlocLoading([]);
Future<void> _onEventQuery(ListImportableAlbumBlocQuery ev,
Emitter<ListImportableAlbumBlocState> emit) async {
emit(const ListImportableAlbumBlocLoading([]));
try {
final albums = (await ListAlbum(_c)(ev.account)
.where((event) => event is Album)
@ -128,15 +130,15 @@ class ListImportableAlbumBloc
products.add(ev);
// don't emit events too frequently
if (++count >= 5) {
yield ListImportableAlbumBlocLoading(products);
emit(ListImportableAlbumBlocLoading(products));
}
}
}
}
yield ListImportableAlbumBlocSuccess(products);
emit(ListImportableAlbumBlocSuccess(products));
} catch (e) {
_log.severe("[_onEventQuery] Exception while request", e);
yield ListImportableAlbumBlocFailure(state.items, e);
emit(ListImportableAlbumBlocFailure(state.items, e));
}
}

View file

@ -70,7 +70,9 @@ class ListPersonBlocFailure extends ListPersonBlocState {
/// List all people recognized in an account
class ListPersonBloc extends Bloc<ListPersonBlocEvent, ListPersonBlocState> {
ListPersonBloc() : super(ListPersonBlocInit());
ListPersonBloc() : super(ListPersonBlocInit()) {
on<ListPersonBlocEvent>(_onEvent);
}
static ListPersonBloc of(Account account) {
final name = bloc_util.getInstNameForAccount("ListPersonBloc", account);
@ -86,21 +88,22 @@ class ListPersonBloc extends Bloc<ListPersonBlocEvent, ListPersonBlocState> {
}
}
@override
mapEventToState(ListPersonBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListPersonBlocEvent event, Emitter<ListPersonBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListPersonBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListPersonBlocState> _onEventQuery(ListPersonBlocQuery ev) async* {
Future<void> _onEventQuery(
ListPersonBlocQuery ev, Emitter<ListPersonBlocState> emit) async {
try {
yield ListPersonBlocLoading(ev.account, state.items);
yield ListPersonBlocSuccess(ev.account, await _query(ev));
emit(ListPersonBlocLoading(ev.account, state.items));
emit(ListPersonBlocSuccess(ev.account, await _query(ev)));
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListPersonBlocFailure(ev.account, state.items, e);
emit(ListPersonBlocFailure(ev.account, state.items, e));
}
}

View file

@ -73,23 +73,26 @@ class ListShareBlocFailure extends ListShareBlocState {
/// List all shares from a given file
class ListShareBloc extends Bloc<ListShareBlocEvent, ListShareBlocState> {
ListShareBloc() : super(ListShareBlocInit());
ListShareBloc() : super(ListShareBlocInit()) {
on<ListShareBlocEvent>(_onEvent);
}
@override
mapEventToState(ListShareBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListShareBlocEvent event, Emitter<ListShareBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListShareBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListShareBlocState> _onEventQuery(ListShareBlocQuery ev) async* {
Future<void> _onEventQuery(
ListShareBlocQuery ev, Emitter<ListShareBlocState> emit) async {
try {
yield ListShareBlocLoading(ev.account, ev.file, state.items);
yield ListShareBlocSuccess(ev.account, ev.file, await _query(ev));
emit(ListShareBlocLoading(ev.account, ev.file, state.items));
emit(ListShareBlocSuccess(ev.account, ev.file, await _query(ev)));
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListShareBlocFailure(ev.account, ev.file, state.items, e);
emit(ListShareBlocFailure(ev.account, ev.file, state.items, e));
}
}

View file

@ -70,7 +70,9 @@ class ListShareeBlocFailure extends ListShareeBlocState {
/// List all sharees of this account
class ListShareeBloc extends Bloc<ListShareeBlocEvent, ListShareeBlocState> {
ListShareeBloc() : super(ListShareeBlocInit());
ListShareeBloc() : super(ListShareeBlocInit()) {
on<ListShareeBlocEvent>(_onEvent);
}
static ListShareeBloc of(Account account) {
final name = bloc_util.getInstNameForAccount("ListShareeBloc", account);
@ -86,21 +88,22 @@ class ListShareeBloc extends Bloc<ListShareeBlocEvent, ListShareeBlocState> {
}
}
@override
mapEventToState(ListShareeBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListShareeBlocEvent event, Emitter<ListShareeBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListShareeBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListShareeBlocState> _onEventQuery(ListShareeBlocQuery ev) async* {
Future<void> _onEventQuery(
ListShareeBlocQuery ev, Emitter<ListShareeBlocState> emit) async {
try {
yield ListShareeBlocLoading(ev.account, state.items);
yield ListShareeBlocSuccess(ev.account, await _query(ev));
emit(ListShareeBlocLoading(ev.account, state.items));
emit(ListShareeBlocSuccess(ev.account, await _query(ev)));
} catch (e, stackTrace) {
_log.shout("[_onEventQuery] Exception while request", e, stackTrace);
yield ListShareeBlocFailure(ev.account, state.items, e);
emit(ListShareeBlocFailure(ev.account, state.items, e));
}
}

View file

@ -166,6 +166,8 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
},
logTag: "ListSharingBloc.refresh",
);
on<ListSharingBlocEvent>(_onEvent);
}
static bool require(DiContainer c) =>
@ -196,48 +198,50 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
return super.close();
}
@override
mapEventToState(ListSharingBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListSharingBlocEvent event, Emitter<ListSharingBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListSharingBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
} else if (event is _ListSharingBlocShareRemoved) {
yield* _onEventShareRemoved(event);
await _onEventShareRemoved(event, emit);
} else if (event is _ListSharingBlocPendingSharedAlbumMoved) {
yield* _onEventPendingSharedAlbumMoved(event);
await _onEventPendingSharedAlbumMoved(event, emit);
}
}
Stream<ListSharingBlocState> _onEventQuery(ListSharingBlocQuery ev) async* {
Future<void> _onEventQuery(
ListSharingBlocQuery ev, Emitter<ListSharingBlocState> emit) async {
try {
yield ListSharingBlocLoading(ev.account, state.items);
yield ListSharingBlocSuccess(ev.account, await _query(ev));
emit(ListSharingBlocLoading(ev.account, state.items));
emit(ListSharingBlocSuccess(ev.account, await _query(ev)));
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListSharingBlocFailure(ev.account, state.items, e);
emit(ListSharingBlocFailure(ev.account, state.items, e));
}
}
Stream<ListSharingBlocState> _onEventShareRemoved(
_ListSharingBlocShareRemoved ev) async* {
Future<void> _onEventShareRemoved(_ListSharingBlocShareRemoved ev,
Emitter<ListSharingBlocState> emit) async {
if (state is! ListSharingBlocSuccess && state is! ListSharingBlocFailure) {
return;
}
final newItems =
state.items.where((i) => !ev.shares.contains(i.share)).toList();
// i love hacks :)
yield (state as dynamic).copyWith(
emit((state as dynamic).copyWith(
items: newItems,
) as ListSharingBlocState;
) as ListSharingBlocState);
}
Stream<ListSharingBlocState> _onEventPendingSharedAlbumMoved(
_ListSharingBlocPendingSharedAlbumMoved ev) async* {
Future<void> _onEventPendingSharedAlbumMoved(
_ListSharingBlocPendingSharedAlbumMoved ev,
Emitter<ListSharingBlocState> emit) async {
if (state.items.isEmpty) {
return;
}
try {
yield ListSharingBlocLoading(ev.account, state.items);
emit(ListSharingBlocLoading(ev.account, state.items));
final items = List.of(state.items);
items.removeWhere(
@ -250,11 +254,11 @@ class ListSharingBloc extends Bloc<ListSharingBlocEvent, ListSharingBlocState> {
items.add(ListSharingAlbum(s, newAlbum));
}
yield ListSharingBlocSuccess(ev.account, items);
emit(ListSharingBlocSuccess(ev.account, items));
} catch (e, stackTrace) {
_log.severe("[_onEventPendingSharedAlbumMoved] Exception while request",
e, stackTrace);
yield ListSharingBlocFailure(ev.account, state.items, e);
emit(ListSharingBlocFailure(ev.account, state.items, e));
}
}

View file

@ -67,7 +67,9 @@ class ListTagBloc extends Bloc<ListTagBlocEvent, ListTagBlocState> {
ListTagBloc(this._c)
: assert(require(_c)),
assert(ListTag.require(_c)),
super(const ListTagBlocInit());
super(const ListTagBlocInit()) {
on<ListTagBlocEvent>(_onEvent);
}
static bool require(DiContainer c) => true;
@ -85,21 +87,22 @@ class ListTagBloc extends Bloc<ListTagBlocEvent, ListTagBlocState> {
}
}
@override
mapEventToState(ListTagBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
ListTagBlocEvent event, Emitter<ListTagBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ListTagBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<ListTagBlocState> _onEventQuery(ListTagBlocQuery ev) async* {
Future<void> _onEventQuery(
ListTagBlocQuery ev, Emitter<ListTagBlocState> emit) async {
try {
yield ListTagBlocLoading(ev.account, state.items);
yield ListTagBlocSuccess(ev.account, await _query(ev));
emit(ListTagBlocLoading(ev.account, state.items));
emit(ListTagBlocSuccess(ev.account, await _query(ev)));
} catch (e, stackTrace) {
_log.severe("[_onEventQuery] Exception while request", e, stackTrace);
yield ListTagBlocFailure(ev.account, state.items, e);
emit(ListTagBlocFailure(ev.account, state.items, e));
}
}

View file

@ -148,23 +148,26 @@ class LsDirBlocFailure extends LsDirBlocState {
/// A bloc that return all directories under a dir recursively
class LsDirBloc extends Bloc<LsDirBlocEvent, LsDirBlocState> {
LsDirBloc(this.fileRepo) : super(LsDirBlocInit());
LsDirBloc(this.fileRepo) : super(LsDirBlocInit()) {
on<LsDirBlocEvent>(_onEvent);
}
@override
mapEventToState(LsDirBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
LsDirBlocEvent event, Emitter<LsDirBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is LsDirBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
}
}
Stream<LsDirBlocState> _onEventQuery(LsDirBlocQuery ev) async* {
Future<void> _onEventQuery(
LsDirBlocQuery ev, Emitter<LsDirBlocState> emit) async {
try {
yield LsDirBlocLoading(ev.account, ev.root, state.items);
yield LsDirBlocSuccess(ev.account, ev.root, await _query(ev));
emit(LsDirBlocLoading(ev.account, ev.root, state.items));
emit(LsDirBlocSuccess(ev.account, ev.root, await _query(ev)));
} catch (e) {
_log.severe("[_onEventQuery] Exception while request", e);
yield LsDirBlocFailure(ev.account, ev.root, state.items, e);
emit(LsDirBlocFailure(ev.account, ev.root, state.items, e));
}
}

View file

@ -106,6 +106,8 @@ class LsTrashbinBloc extends Bloc<LsTrashbinBlocEvent, LsTrashbinBlocState> {
},
logTag: "LsTrashbinBloc.refresh",
);
on<LsTrashbinBlocEvent>(_onEvent);
}
static LsTrashbinBloc of(Account account) {
@ -122,29 +124,30 @@ class LsTrashbinBloc extends Bloc<LsTrashbinBlocEvent, LsTrashbinBlocState> {
}
}
@override
mapEventToState(LsTrashbinBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(
LsTrashbinBlocEvent event, Emitter<LsTrashbinBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is LsTrashbinBlocQuery) {
yield* _onEventQuery(event);
await _onEventQuery(event, emit);
} else if (event is _LsTrashbinBlocExternalEvent) {
yield* _onExternalEvent(event);
await _onExternalEvent(event, emit);
}
}
Stream<LsTrashbinBlocState> _onEventQuery(LsTrashbinBlocQuery ev) async* {
Future<void> _onEventQuery(
LsTrashbinBlocQuery ev, Emitter<LsTrashbinBlocState> emit) async {
try {
yield LsTrashbinBlocLoading(ev.account, state.items);
yield LsTrashbinBlocSuccess(ev.account, await _query(ev));
emit(LsTrashbinBlocLoading(ev.account, state.items));
emit(LsTrashbinBlocSuccess(ev.account, await _query(ev)));
} catch (e) {
_log.severe("[_onEventQuery] Exception while request", e);
yield LsTrashbinBlocFailure(ev.account, state.items, e);
emit(LsTrashbinBlocFailure(ev.account, state.items, e));
}
}
Stream<LsTrashbinBlocState> _onExternalEvent(
_LsTrashbinBlocExternalEvent ev) async* {
yield LsTrashbinBlocInconsistent(state.account, state.items);
Future<void> _onExternalEvent(_LsTrashbinBlocExternalEvent ev,
Emitter<LsTrashbinBlocState> emit) async {
emit(LsTrashbinBlocInconsistent(state.account, state.items));
}
void _onFileRemovedEvent(FileRemovedEvent ev) {

View file

@ -117,6 +117,19 @@ class ScanAccountDirBloc
_accountPrefUpdatedEventListener.begin();
_nativeFileExifUpdatedListener?.begin();
on<ScanAccountDirBlocEvent>(_onEvent, transformer: ((events, mapper) {
return events.asyncExpand(mapper).distinct((a, b) {
// only handle ScanAccountDirBlocQuery
final r = a is ScanAccountDirBlocQuery &&
b is ScanAccountDirBlocQuery &&
a == b;
if (r) {
_log.fine("[on] Skip identical ScanAccountDirBlocQuery event");
}
return r;
});
}));
}
static ScanAccountDirBloc of(Account account) {
@ -134,31 +147,6 @@ class ScanAccountDirBloc
}
}
@override
transformEvents(Stream<ScanAccountDirBlocEvent> events, transitionFn) {
return super.transformEvents(events.distinct((a, b) {
// only handle ScanAccountDirBlocQuery
final r = a is ScanAccountDirBlocQuery &&
b is ScanAccountDirBlocQuery &&
a == b;
if (r) {
_log.fine(
"[transformEvents] Skip identical ScanAccountDirBlocQuery event");
}
return r;
}), transitionFn);
}
@override
mapEventToState(ScanAccountDirBlocEvent event) async* {
_log.info("[mapEventToState] $event");
if (event is ScanAccountDirBlocQueryBase) {
yield* _onEventQuery(event);
} else if (event is _ScanAccountDirBlocExternalEvent) {
yield* _onExternalEvent(event);
}
}
@override
close() {
_fileRemovedEventListener.end();
@ -175,9 +163,20 @@ class ScanAccountDirBloc
return super.close();
}
Stream<ScanAccountDirBlocState> _onEventQuery(
ScanAccountDirBlocQueryBase ev) async* {
yield ScanAccountDirBlocLoading(state.files);
Future<void> _onEvent(ScanAccountDirBlocEvent event,
Emitter<ScanAccountDirBlocState> emit) async {
_log.info("[_onEvent] $event");
if (event is ScanAccountDirBlocQueryBase) {
await _onEventQuery(event, emit);
} else if (event is _ScanAccountDirBlocExternalEvent) {
await _onExternalEvent(event, emit);
}
}
Future<void> _onEventQuery(ScanAccountDirBlocQueryBase ev,
Emitter<ScanAccountDirBlocState> emit) async {
_log.info("[_onEventQuery] $ev");
emit(ScanAccountDirBlocLoading(state.files));
final hasContent = state.files.isNotEmpty;
final stopwatch = Stopwatch()..start();
@ -186,16 +185,16 @@ class ScanAccountDirBloc
"[_onEventQuery] Elapsed time (_queryOffline): ${stopwatch.elapsedMilliseconds}ms");
if (!hasContent) {
// show something instantly on first load
yield ScanAccountDirBlocLoading(
cacheFiles.where((f) => file_util.isSupportedFormat(f)).toList());
emit(ScanAccountDirBlocLoading(
cacheFiles.where((f) => file_util.isSupportedFormat(f)).toList()));
}
yield* _queryOnline(ev, cacheFiles);
await _queryOnline(ev, emit, cacheFiles);
}
Stream<ScanAccountDirBlocState> _onExternalEvent(
_ScanAccountDirBlocExternalEvent ev) async* {
yield ScanAccountDirBlocInconsistent(state.files);
Future<void> _onExternalEvent(_ScanAccountDirBlocExternalEvent ev,
Emitter<ScanAccountDirBlocState> emit) async {
emit(ScanAccountDirBlocInconsistent(state.files));
}
void _onFileRemovedEvent(FileRemovedEvent ev) {
@ -335,8 +334,8 @@ class ScanAccountDirBloc
return files;
}
Stream<ScanAccountDirBlocState> _queryOnline(
ScanAccountDirBlocQueryBase ev, List<File> cache) async* {
Future<void> _queryOnline(ScanAccountDirBlocQueryBase ev,
Emitter<ScanAccountDirBlocState> emit, List<File> cache) async {
// 1st pass: scan for new files
var files = <File>[];
final cacheMap = FileForwardCacheManager.prepareFileMap(cache);
@ -350,17 +349,17 @@ class ScanAccountDirBloc
if (event is ExceptionEvent) {
_log.shout("[_queryOnline] Exception while request (1st pass)",
event.error, event.stackTrace);
yield ScanAccountDirBlocFailure(
emit(ScanAccountDirBlocFailure(
cache.isEmpty
? files
: cache.where((f) => file_util.isSupportedFormat(f)).toList(),
event.error);
event.error));
return;
}
files.addAll(event);
if (cache.isEmpty) {
// only emit partial results if there's no cache
yield ScanAccountDirBlocLoading(files);
emit(ScanAccountDirBlocLoading(files));
}
}
_log.info(
@ -376,7 +375,7 @@ class ScanAccountDirBloc
// if cache is empty, we have already emitted the results in the loop
if (cache.isNotEmpty || files.isEmpty) {
// emit results from remote
yield ScanAccountDirBlocLoading(files);
emit(ScanAccountDirBlocLoading(files));
}
files = await _queryOnlinePass2(ev, cacheMap, files);
@ -385,7 +384,7 @@ class ScanAccountDirBloc
_log.shout(
"[_queryOnline] Failed while _queryOnlinePass2", e, stackTrace);
}
yield ScanAccountDirBlocSuccess(files);
emit(ScanAccountDirBlocSuccess(files));
}
Future<List<File>> _queryOnlinePass2(ScanAccountDirBlocQueryBase ev,

View file

@ -66,21 +66,23 @@ class SearchSuggestionBloc<T>
extends Bloc<SearchSuggestionBlocEvent, SearchSuggestionBlocState<T>> {
SearchSuggestionBloc({
required this.itemToKeywords,
}) : super(SearchSuggestionBlocInit<T>());
}) : super(SearchSuggestionBlocInit<T>()) {
on<SearchSuggestionBlocEvent>(_onEvent);
}
@override
mapEventToState(SearchSuggestionBlocEvent event) async* {
_log.info("[mapEventToState] $event");
Future<void> _onEvent(SearchSuggestionBlocEvent event,
Emitter<SearchSuggestionBlocState<T>> emit) async {
_log.info("[_onEvent] $event");
if (event is SearchSuggestionBlocSearchEvent) {
yield* _onEventSearch(event);
await _onEventSearch(event, emit);
} else if (event is SearchSuggestionBlocUpdateItemsEvent<T>) {
yield* _onEventUpdateItems(event);
await _onEventUpdateItems(event, emit);
}
}
Stream<SearchSuggestionBlocState<T>> _onEventSearch(
SearchSuggestionBlocSearchEvent ev) async* {
yield SearchSuggestionBlocLoading(state.results);
Future<void> _onEventSearch(SearchSuggestionBlocSearchEvent ev,
Emitter<SearchSuggestionBlocState<T>> emit) async {
emit(SearchSuggestionBlocLoading(state.results));
// doesn't work with upper case
final results = _search.search(ev.phrase.toCaseInsensitiveString());
if (kDebugMode) {
@ -106,12 +108,12 @@ class SearchSuggestionBloc<T>
)
.map((e) => e.item2)
.toList();
yield SearchSuggestionBlocSuccess(matches);
emit(SearchSuggestionBlocSuccess(matches));
_lastSearch = ev;
}
Stream<SearchSuggestionBlocState<T>> _onEventUpdateItems(
SearchSuggestionBlocUpdateItemsEvent<T> ev) async* {
Future<void> _onEventUpdateItems(SearchSuggestionBlocUpdateItemsEvent<T> ev,
Emitter<SearchSuggestionBlocState<T>> emit) async {
_search.setEntries([]);
for (final a in ev.items) {
for (final k in itemToKeywords(a)) {
@ -120,7 +122,7 @@ class SearchSuggestionBloc<T>
}
if (_lastSearch != null) {
// search again
yield* _onEventSearch(_lastSearch!);
await _onEventSearch(_lastSearch!, emit);
}
}

View file

@ -25,7 +25,7 @@ class NativeEventListener<T> {
_subscription = null;
}
static late final _mappedStream =
static final _mappedStream =
NativeEvent.stream.whereType<NativeEventObject>().map((ev) {
switch (ev.event) {
case FileExifUpdatedEvent._id:

View file

@ -84,6 +84,14 @@ extension IterableExtension<T> on Iterable<T> {
}
}
extension IterableFlattenExtension<T> on Iterable<Iterable<T>> {
/// Flattens an [Iterable] of [Iterable] values of type [T] to a [Iterable] of
/// values of type [T].
///
/// This function originated in the xml package
Iterable<T> flatten() => expand((values) => values);
}
class _ComputeAllMessage<T, U> {
const _ComputeAllMessage(this.callback, this.data);

View file

@ -1,5 +1,8 @@
import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/app_init.dart' as app_init;
import 'package:nc_photos/platform/k.dart' as platform_k;
import 'package:nc_photos/widget/my_app.dart';
@ -12,5 +15,19 @@ void main() async {
// reset orientation override just in case, see #59
SystemChrome.setPreferredOrientations([]);
}
runApp(const MyApp());
BlocOverrides.runZoned(
() => runApp(const MyApp()),
blocObserver: _BlocObserver(),
eventTransformer: sequential(),
);
}
class _BlocObserver extends BlocObserver {
@override
onChange(BlocBase bloc, Change change) {
super.onChange(bloc, change);
_log.finer("${bloc.runtimeType} $change");
}
static final _log = Logger("main._BlocObserver");
}

View file

@ -12,7 +12,7 @@ class DownloadEvent {
static const _downloadCancelChannel = EventChannel(
"com.nkming.nc_photos/download_event/action_download_cancel");
static late final _cancelStream = _downloadCancelChannel
static final _cancelStream = _downloadCancelChannel
.receiveBroadcastStream()
.map((data) => DownloadCancelEvent(
data["notificationId"],

View file

@ -210,7 +210,7 @@ class _L10n {
}
}
static late final _inst = _L10n._();
static final _inst = _L10n._();
late AppLocalizations _l10n;
static final _log = Logger("service._L10n");

View file

@ -0,0 +1,4 @@
import 'package:url_launcher/url_launcher_string.dart';
Future<bool> launch(String url) =>
launchUrlString(url, mode: LaunchMode.externalApplication);

View file

@ -1,9 +1,9 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:html';
import 'package:/nc_photos/mobile/ui_hack.dart' if (dart.library.html) 'dart:ui'
as ui;
import 'package:flutter/widgets.dart';
import 'package:nc_photos/mobile/ui_hack.dart' if (dart.library.html) 'dart:ui'
as ui;
import 'package:tuple/tuple.dart';
class GoogleGpsMap extends StatefulWidget {

View file

@ -231,11 +231,11 @@ mixin AlbumBrowserMixin<T extends StatefulWidget>
)();
} catch (e, stackTrace) {
_log.shout(
"[_onAddToCollectionPressed] Failed while ImportPendingSharedAlbum: ${logFilename(album.albumFile?.path)}",
"[_onAddToCollectionPressed] Failed while _onAddToCollectionPressed: ${logFilename(album.albumFile?.path)}",
e,
stackTrace);
}
if (newAlbum != null) {
if (newAlbum != null && mounted) {
album_browser_util.pushReplacement(context, account, newAlbum!);
}
}

View file

@ -178,7 +178,7 @@ class _AlbumImporterState extends State<AlbumImporter> {
icon: AnimatedSwitcher(
duration: k.animationDurationShort,
transitionBuilder: (child, animation) =>
ScaleTransition(child: child, scale: animation),
ScaleTransition(scale: animation, child: child),
child: Icon(
isPicked ? Icons.check_box : Icons.check_box_outline_blank,
key: ValueKey(isPicked),
@ -218,7 +218,9 @@ class _AlbumImporterState extends State<AlbumImporter> {
// make sure we dismiss the dialog in any cases
Navigator.of(context).pop();
}
Navigator.of(context).pop();
if (mounted) {
Navigator.of(context).pop();
}
}
Future<void> _createAllAlbums(BuildContext context) async {

View file

@ -22,8 +22,8 @@ import 'package:nc_photos/platform/features.dart' as features;
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/string_extension.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:nc_photos/use_case/ls_single_file.dart';
import 'package:url_launcher/url_launcher.dart';
class ConnectArguments {
ConnectArguments(this.account);

View file

@ -95,11 +95,11 @@ class DirPickerState extends State<DirPicker> {
duration: k.animationDurationNormal,
// see AnimatedSwitcher.defaultLayoutBuilder
layoutBuilder: (currentChild, previousChildren) => Stack(
alignment: Alignment.topLeft,
children: <Widget>[
...previousChildren,
if (currentChild != null) currentChild,
],
alignment: Alignment.topLeft,
),
// needed to prevent background color overflowing the parent bound, see:
// https://github.com/flutter/flutter/issues/86584
@ -171,7 +171,7 @@ class DirPickerState extends State<DirPicker> {
icon: AnimatedSwitcher(
duration: k.animationDurationShort,
transitionBuilder: (child, animation) =>
ScaleTransition(child: child, scale: animation),
ScaleTransition(scale: animation, child: child),
child: Icon(
iconData,
key: ValueKey(pickState),

View file

@ -57,11 +57,11 @@ class Draggable<T extends Object> extends StatelessWidget {
),
),
),
child: child,
childWhenDragging: Opacity(
opacity: .25,
child: child,
),
child: child,
),
),
if (onDropBefore != null || onDropAfter != null)

View file

@ -44,13 +44,13 @@ mixin DraggableItemListMixin<T extends StatefulWidget> on State<T> {
final item = _items[index];
return my.Draggable(
data: item,
child: item.buildWidget(context),
feedback: item.buildDragFeedbackWidget(context),
onDropBefore: item.onDropBefore,
onDropAfter: item.onDropAfter,
onDragStarted: item.onDragStarted,
onDragEndedAny: item.onDragEndedAny,
feedbackSize: Size(_maxCrossAxisExtent * .65, _maxCrossAxisExtent * .65),
child: item.buildWidget(context),
);
}

View file

@ -4,8 +4,8 @@ import 'package:latlong2/latlong.dart';
import 'package:nc_photos/mobile/platform.dart'
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:tuple/tuple.dart';
import 'package:url_launcher/url_launcher.dart';
enum GpsMapProvider {
// the order must not be changed
@ -88,15 +88,14 @@ class _OsmGpsMap extends StatelessWidget {
enableScrollWheel: false,
interactiveFlags: InteractiveFlag.none,
),
nonRotatedChildren: [
AttributionWidget.defaultWidget(
source: "OpenStreetMap contributors",
),
],
layers: [
TileLayerOptions(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
attributionBuilder: (_) {
return const Text(
"© OpenStreetMap contributors",
style: TextStyle(color: Colors.black),
);
},
),
MarkerLayerOptions(
markers: [

View file

@ -20,11 +20,11 @@ import 'package:nc_photos/platform/k.dart' as platform_k;
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:nc_photos/widget/selectable.dart';
import 'package:nc_photos/widget/settings.dart';
import 'package:nc_photos/widget/stateful_slider.dart';
import 'package:nc_photos_plugin/nc_photos_plugin.dart';
import 'package:url_launcher/url_launcher.dart';
class EnhanceHandler {
const EnhanceHandler({

View file

@ -7,9 +7,9 @@ import 'package:nc_photos/event/event.dart';
import 'package:nc_photos/help_utils.dart' as help_utils;
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:nc_photos/widget/account_picker_dialog.dart';
import 'package:nc_photos/widget/settings.dart';
import 'package:url_launcher/url_launcher.dart';
/// AppBar for home screens
class HomeSliverAppBar extends StatelessWidget {

View file

@ -18,9 +18,9 @@ import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:nc_photos/widget/empty_list_indicator.dart';
import 'package:nc_photos/widget/person_browser.dart';
import 'package:url_launcher/url_launcher.dart';
class PeopleBrowserArguments {
PeopleBrowserArguments(this.account);

View file

@ -33,6 +33,7 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
Row(
children: [
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().dateYearInputHint,
@ -51,10 +52,10 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
},
initialValue: "${widget.initialDateTime.year}",
),
flex: 1,
),
const SizedBox(width: 4),
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().dateMonthInputHint,
@ -72,10 +73,10 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
initialValue:
widget.initialDateTime.month.toString().padLeft(2, "0"),
),
flex: 1,
),
const SizedBox(width: 4),
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().dateDayInputHint,
@ -93,7 +94,6 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
initialValue:
widget.initialDateTime.day.toString().padLeft(2, "0"),
),
flex: 1,
),
],
),
@ -105,6 +105,7 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
Row(
children: [
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().timeHourInputHint,
@ -122,10 +123,10 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
initialValue:
widget.initialDateTime.hour.toString().padLeft(2, "0"),
),
flex: 1,
),
const SizedBox(width: 4),
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().timeMinuteInputHint,
@ -144,12 +145,11 @@ class _PhotoDateTimeEditDialogState extends State<PhotoDateTimeEditDialog> {
.toString()
.padLeft(2, "0"),
),
flex: 1,
),
const SizedBox(width: 4),
const Flexible(
child: SizedBox(),
flex: 1,
child: SizedBox(),
),
],
),

View file

@ -19,6 +19,7 @@ import 'package:nc_photos/pref.dart';
import 'package:nc_photos/service.dart';
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:nc_photos/widget/fancy_option_picker.dart';
import 'package:nc_photos/widget/gps_map.dart';
import 'package:nc_photos/widget/home.dart';
@ -28,7 +29,6 @@ import 'package:nc_photos/widget/share_folder_picker.dart';
import 'package:nc_photos/widget/stateful_slider.dart';
import 'package:screen_brightness/screen_brightness.dart';
import 'package:tuple/tuple.dart';
import 'package:url_launcher/url_launcher.dart';
class SettingsArguments {
SettingsArguments(this.account);
@ -1504,6 +1504,6 @@ enum _Experiment {
sharedAlbum,
}
late final _enabledExperiments = [
final _enabledExperiments = [
_Experiment.sharedAlbum,
];

View file

@ -100,6 +100,7 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
);
}
return SimpleDialogOption(
onPressed: isProcessing ? () {} : () => _onShareItemPressed(share),
child: ListTile(
title: Text(share.displayName),
subtitle: Text(share.shareWith.toString()),
@ -108,7 +109,6 @@ class _ShareAlbumDialogState extends State<ShareAlbumDialog> {
child: trailing,
),
),
onPressed: isProcessing ? () {} : () => _onShareItemPressed(share),
);
}

View file

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:nc_photos/app_localizations.dart';
import 'package:nc_photos/help_utils.dart' as help_utils;
import 'package:nc_photos/pref.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:nc_photos/url_launcher_util.dart';
class SharedAlbumInfoDialog extends StatefulWidget {
const SharedAlbumInfoDialog({

View file

@ -226,7 +226,9 @@ class _SharedFileViewerState extends State<SharedFileViewer> {
}
}
} finally {
Navigator.of(context).pop();
if (mounted) {
Navigator.of(context).pop();
}
}
} else {
setState(() {

View file

@ -10,10 +10,10 @@ import 'package:nc_photos/pref.dart';
import 'package:nc_photos/pref_util.dart' as pref_util;
import 'package:nc_photos/string_extension.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/url_launcher_util.dart';
import 'package:nc_photos/widget/connect.dart';
import 'package:nc_photos/widget/home.dart';
import 'package:nc_photos/widget/root_picker.dart';
import 'package:url_launcher/url_launcher.dart';
class SignIn extends StatefulWidget {
static const routeName = "/sign-in";

View file

@ -73,6 +73,7 @@ class _SlideshowDialogState extends State<SlideshowDialog> {
Row(
children: [
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().timeMinuteInputHint,
@ -98,12 +99,12 @@ class _SlideshowDialogState extends State<SlideshowDialog> {
initialValue:
widget.duration.inMinutes.toString().padLeft(2, "0"),
),
flex: 1,
),
const SizedBox(width: 4),
const Text(":"),
const SizedBox(width: 4),
Flexible(
flex: 1,
child: TextFormField(
decoration: InputDecoration(
hintText: L10n.global().timeSecondInputHint,
@ -130,7 +131,6 @@ class _SlideshowDialogState extends State<SlideshowDialog> {
.toString()
.padLeft(2, "0"),
),
flex: 1,
),
],
),

View file

@ -172,7 +172,9 @@ class _TrashbinViewerState extends State<TrashbinViewer> {
content: Text(L10n.global().restoreSuccessNotification),
duration: k.snackBarDurationNormal,
));
Navigator.of(context).pop();
if (mounted) {
Navigator.of(context).pop();
}
} catch (e, stacktrace) {
_log.shout("Failed while restore trashbin: ${logFilename(file.path)}", e,
stacktrace);
@ -314,7 +316,7 @@ class _TrashbinViewerState extends State<TrashbinViewer> {
shouldCleanupAlbum: false,
isRemoveOpened: true,
);
if (count > 0) {
if (count > 0 && mounted) {
Navigator.of(context).pop();
}
}

View file

@ -599,7 +599,7 @@ class _ViewerState extends State<Viewer>
isRemoveOpened: true,
isMoveToTrash: true,
);
if (count > 0) {
if (count > 0 && mounted) {
Navigator.of(context).pop();
}
}

View file

@ -7,14 +7,14 @@ packages:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "40.0.0"
version: "41.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.0"
version: "4.2.0"
android_intent_plus:
dependency: "direct main"
description:
@ -30,35 +30,35 @@ packages:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
version: "2.3.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
version: "2.9.0"
battery_plus:
dependency: "direct main"
description:
name: battery_plus
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.1.4"
battery_plus_linux:
dependency: transitive
description:
name: battery_plus_linux
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
version: "1.1.2"
battery_plus_macos:
dependency: transitive
description:
name: battery_plus_macos
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.1"
battery_plus_platform_interface:
dependency: transitive
description:
@ -79,21 +79,28 @@ packages:
name: battery_plus_windows
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.2"
bloc:
dependency: "direct main"
description:
name: bloc
url: "https://pub.dartlang.org"
source: hosted
version: "7.2.1"
version: "8.0.3"
bloc_concurrency:
dependency: "direct main"
description:
name: bloc_concurrency
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
bloc_test:
dependency: "direct dev"
description:
name: bloc_test
url: "https://pub.dartlang.org"
source: hosted
version: "8.5.0"
version: "9.0.3"
boolean_selector:
dependency: transitive
description:
@ -156,84 +163,84 @@ packages:
name: connectivity_plus
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.3.5"
connectivity_plus_linux:
dependency: transitive
description:
name: connectivity_plus_linux
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.3.1"
connectivity_plus_macos:
dependency: transitive
description:
name: connectivity_plus_macos
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
version: "1.2.4"
connectivity_plus_platform_interface:
dependency: transitive
description:
name: connectivity_plus_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.1"
connectivity_plus_web:
dependency: transitive
description:
name: connectivity_plus_web
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0+1"
version: "1.2.2"
connectivity_plus_windows:
dependency: transitive
description:
name: connectivity_plus_windows
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.2"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
version: "3.0.2"
coverage:
dependency: transitive
description:
name: coverage
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
version: "1.5.0"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
version: "3.0.2"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.17.1"
version: "0.17.2"
dbus:
dependency: transitive
description:
name: dbus
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.3"
version: "0.7.6"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
version: "4.0.0"
device_info_plus_linux:
dependency: transitive
description:
@ -247,7 +254,7 @@ packages:
name: device_info_plus_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.2"
version: "2.2.3"
device_info_plus_platform_interface:
dependency: transitive
description:
@ -263,12 +270,12 @@ packages:
source: hosted
version: "2.1.0"
device_info_plus_windows:
dependency: transitive
dependency: "direct overridden"
description:
name: device_info_plus_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "3.0.0"
devicelocale:
dependency: "direct main"
description:
@ -315,20 +322,13 @@ packages:
url: "https://gitlab.com/nc-photos/exifdart.git"
source: git
version: "1.2.0"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
version: "2.0.1"
file:
dependency: transitive
description:
@ -356,14 +356,14 @@ packages:
name: flutter_bloc
url: "https://pub.dartlang.org"
source: hosted
version: "7.3.3"
version: "8.0.1"
flutter_blurhash:
dependency: transitive
description:
name: flutter_blurhash
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.0"
version: "0.7.0"
flutter_cache_manager:
dependency: transitive
description:
@ -377,7 +377,7 @@ packages:
name: flutter_keyboard_visibility
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.1"
version: "5.3.0"
flutter_keyboard_visibility_platform_interface:
dependency: transitive
description:
@ -398,7 +398,7 @@ packages:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
version: "2.0.1"
flutter_localizations:
dependency: "direct main"
description: flutter
@ -410,14 +410,14 @@ packages:
name: flutter_map
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0"
version: "1.1.1"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.0.6"
flutter_staggered_grid_view:
dependency: "direct main"
description:
@ -427,11 +427,6 @@ packages:
url: "https://gitlab.com/nc-photos/flutter_staggered_grid_view"
source: git
version: "0.4.0"
flutter_test:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_typeahead:
dependency: "direct main"
description:
@ -450,28 +445,28 @@ packages:
name: frontend_server_client
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
version: "2.1.3"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.1.0"
google_maps_flutter:
dependency: "direct main"
description:
name: google_maps_flutter
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
version: "2.1.8"
google_maps_flutter_platform_interface:
dependency: transitive
description:
name: google_maps_flutter_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
version: "2.2.0"
hashcodes:
dependency: transitive
description:
@ -499,14 +494,14 @@ packages:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
version: "3.2.1"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
version: "4.0.1"
idb_shim:
dependency: "direct main"
description:
@ -557,7 +552,7 @@ packages:
name: kiwi
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.1"
version: "4.0.2"
latlong2:
dependency: transitive
description:
@ -571,7 +566,7 @@ packages:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "2.0.0"
lists:
dependency: transitive
description:
@ -592,7 +587,7 @@ packages:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.11"
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
@ -634,14 +629,14 @@ packages:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.0.2"
mocktail:
dependency: transitive
description:
name: mocktail
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
version: "0.3.0"
mutex:
dependency: "direct main"
description:
@ -655,7 +650,7 @@ packages:
name: native_device_orientation
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.4"
nc_photos_plugin:
dependency: "direct main"
description:
@ -690,14 +685,14 @@ packages:
name: octo_image
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.0.2"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.1.0"
page_view_indicators:
dependency: "direct main"
description:
@ -718,49 +713,49 @@ packages:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
version: "2.0.11"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.11"
version: "2.0.16"
path_provider_ios:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.7"
version: "2.0.10"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
version: "2.1.7"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.0.6"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
version: "2.0.4"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.1.0"
pedantic:
dependency: transitive
description:
@ -774,7 +769,7 @@ packages:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "4.4.0"
version: "5.0.0"
platform:
dependency: transitive
description:
@ -789,13 +784,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
polylabel:
dependency: transitive
description:
name: polylabel
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.5.0"
version: "1.5.1"
positioned_tap_detector_2:
dependency: transitive
description:
@ -823,56 +825,63 @@ packages:
name: provider
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.2"
version: "6.0.3"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.1.1"
quiver:
dependency: transitive
dependency: "direct main"
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1+1"
version: "3.1.0"
rxdart:
dependency: "direct main"
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
source: hosted
version: "0.27.3"
version: "0.27.4"
screen_brightness:
dependency: "direct main"
description:
name: screen_brightness
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
version: "0.2.1"
screen_brightness_android:
dependency: transitive
description:
name: screen_brightness_android
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
version: "0.1.0"
screen_brightness_ios:
dependency: transitive
description:
name: screen_brightness_ios
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
version: "0.1.0"
screen_brightness_macos:
dependency: transitive
description:
name: screen_brightness_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+1"
screen_brightness_platform_interface:
dependency: transitive
description:
name: screen_brightness_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
version: "0.1.0"
sembast:
dependency: transitive
description:
@ -886,35 +895,35 @@ packages:
name: shared_preferences
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
version: "2.0.15"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.10"
version: "2.0.12"
shared_preferences_ios:
dependency: transitive
description:
name: shared_preferences_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
version: "2.1.1"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
version: "2.1.1"
shared_preferences_macos:
dependency: transitive
description:
name: shared_preferences_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.0.4"
shared_preferences_platform_interface:
dependency: transitive
description:
@ -928,42 +937,42 @@ packages:
name: shared_preferences_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.3"
version: "2.0.4"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
version: "2.1.1"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.3.1"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
version: "3.0.1"
shelf_static:
dependency: transitive
description:
name: shelf_static
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.1"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
version: "1.0.2"
sky_engine:
dependency: transitive
description: flutter
@ -989,21 +998,21 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
version: "1.9.0"
sqflite:
dependency: "direct main"
description:
name: sqflite
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "2.0.3"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1+1"
version: "2.2.1+1"
stack_trace:
dependency: transitive
description:
@ -1031,49 +1040,42 @@ packages:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
version: "1.1.1"
synchronized:
dependency: "direct main"
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
version: "3.0.0+2"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
version: "1.2.1"
test:
dependency: "direct dev"
description:
name: test
url: "https://pub.dartlang.org"
source: hosted
version: "1.21.1"
version: "1.21.4"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.9"
version: "0.4.12"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.13"
transparent_image:
dependency: transitive
description:
name: transparent_image
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "0.4.16"
tuple:
dependency: "direct main"
description:
@ -1087,7 +1089,7 @@ packages:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
version: "1.3.1"
unicode:
dependency: transitive
description:
@ -1101,63 +1103,63 @@ packages:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.17"
version: "6.1.4"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.13"
version: "6.0.17"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.13"
version: "6.0.17"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "3.0.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "3.0.1"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
version: "2.1.0"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.5"
version: "2.0.12"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2"
version: "3.0.1"
uuid:
dependency: transitive
dependency: "direct main"
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.5"
version: "3.0.6"
vector_math:
dependency: transitive
description:
@ -1168,30 +1170,40 @@ packages:
video_player:
dependency: "direct main"
description:
path: "packages/video_player/video_player"
ref: "video_player-v2.2.6-nc-photos-2"
resolved-ref: "176a4e719a376c8f686a0ed73900b171cf92ebf0"
name: video_player
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.5"
video_player_android:
dependency: "direct overridden"
description:
path: "packages/video_player/video_player_android"
ref: "video_player-v2.4.5-nc-photos-1"
resolved-ref: fade05907d60e1076c270cd41a5f2b842c4a4d00
url: "https://gitlab.com/nc-photos/flutter-plugins"
source: git
version: "2.2.6"
version: "2.3.6"
video_player_avfoundation:
dependency: transitive
description:
name: video_player_avfoundation
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.5"
video_player_platform_interface:
dependency: transitive
description:
path: "packages/video_player/video_player_platform_interface"
ref: "video_player-v2.2.6-nc-photos-2"
resolved-ref: "176a4e719a376c8f686a0ed73900b171cf92ebf0"
url: "https://gitlab.com/nc-photos/flutter-plugins"
source: git
version: "4.2.0"
name: video_player_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "5.1.3"
video_player_web:
dependency: transitive
description:
path: "packages/video_player/video_player_web"
ref: "video_player-v2.2.6-nc-photos-2"
resolved-ref: "176a4e719a376c8f686a0ed73900b171cf92ebf0"
url: "https://gitlab.com/nc-photos/flutter-plugins"
source: git
version: "2.0.4"
name: video_player_web
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.10"
visibility_detector:
dependency: "direct main"
description:
@ -1205,14 +1217,14 @@ packages:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
version: "7.5.0"
version: "9.0.0"
wakelock:
dependency: "direct main"
description:
name: wakelock
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.6"
version: "0.6.2"
wakelock_macos:
dependency: transitive
description:
@ -1254,21 +1266,21 @@ packages:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.2.0"
webkit_inspection_protocol:
dependency: transitive
description:
name: webkit_inspection_protocol
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
version: "1.1.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.6.1"
version: "2.7.0"
wkt_parser:
dependency: transitive
description:
@ -1296,14 +1308,14 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "5.3.1"
version: "6.1.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
version: "3.1.1"
sdks:
dart: ">=2.17.0 <3.0.0"
flutter: ">=3.0.0"

View file

@ -34,12 +34,13 @@ dependencies:
ref: android_intent_plus-v3.1.1-nc-photos-1
path: packages/android_intent_plus
battery_plus: ^2.1.3
bloc: ^7.0.0
bloc: ^8.0.0
bloc_concurrency: ^0.2.0
cached_network_image: ^3.2.1
collection: ^1.15.0
connectivity_plus: ^2.0.2
devicelocale: ^0.5.0
device_info_plus: ^3.1.0
device_info_plus: ^4.0.0
draggable_scrollbar:
git:
url: https://gitlab.com/nc-photos/flutter-draggable-scrollbar
@ -54,8 +55,8 @@ dependencies:
git:
url: https://gitlab.com/nc-photos/flutter_background_service.git
ref: v0.2.6-nc-photos-2
flutter_bloc: ^7.0.0
flutter_map: ^0.14.0
flutter_bloc: ^8.0.0
flutter_map: ^1.1.1
flutter_staggered_grid_view:
git:
url: https://gitlab.com/nc-photos/flutter_staggered_grid_view
@ -78,34 +79,41 @@ dependencies:
memory_info: ^0.0.2
mime: ^1.0.1
mutex: ^3.0.0
native_device_orientation: 1.1.0
native_device_orientation: ^1.1.0
nc_photos_plugin:
path: ../plugin
page_view_indicators: ^2.0.0
path: ^1.8.0
path_provider: ^2.0.6
rxdart: ^0.27.2
screen_brightness: ^0.1.1
quiver: ^3.1.0
screen_brightness: ^0.2.1
shared_preferences: ^2.0.8
# android/ios only
sqflite: ^2.0.0
synchronized: ^3.0.0
tuple: ^2.0.0
url_launcher: ^6.0.3
video_player:
uuid: ^3.0.6
video_player: 2.4.5
visibility_detector: ^0.3.3
wakelock: ^0.6.2
woozy_search: ^2.0.3
xml: ^6.1.0
dependency_overrides:
# the dependency of device_info_plus_windows was set incorrectly in
# device_info_plus, this is a workaround until it's fixed in upstream
device_info_plus_windows: ^3.0.0
video_player_android:
git:
url: https://gitlab.com/nc-photos/flutter-plugins
ref: video_player-v2.2.6-nc-photos-2
path: packages/video_player/video_player
visibility_detector: ^0.3.3
wakelock: ^0.5.2
woozy_search: ^2.0.3
xml: ^5.0.2
ref: video_player-v2.4.5-nc-photos-1
path: packages/video_player/video_player_android
dev_dependencies:
test: any
bloc_test: any
flutter_lints: ^1.0.4
flutter_lints: ^2.0.1
# flutter_test:
# sdk: flutter
# integration_test: