mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 16:56:19 +01:00
Don't try to query ncalbum when Nextcloud <25
This commit is contained in:
parent
499583d76f
commit
2b177d7679
16 changed files with 215 additions and 19 deletions
|
@ -7,6 +7,7 @@ import 'package:nc_photos/entity/file.dart';
|
|||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/nc_album_item.dart';
|
||||
import 'package:nc_photos/entity/person.dart';
|
||||
import 'package:nc_photos/entity/server_status.dart';
|
||||
import 'package:nc_photos/entity/share.dart';
|
||||
import 'package:nc_photos/entity/sharee.dart';
|
||||
import 'package:nc_photos/entity/tag.dart';
|
||||
|
@ -179,6 +180,16 @@ class ApiShareeConverter {
|
|||
};
|
||||
}
|
||||
|
||||
class ApiStatusConverter {
|
||||
static ServerStatus fromApi(api.Status status) {
|
||||
return ServerStatus(
|
||||
versionRaw: status.version,
|
||||
versionName: status.versionString,
|
||||
productName: status.productName,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ApiTagConverter {
|
||||
static Tag fromApi(api.Tag tag) {
|
||||
return Tag(
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:kiwi/kiwi.dart';
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/controller/collections_controller.dart';
|
||||
import 'package:nc_photos/controller/server_controller.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/collection.dart';
|
||||
import 'package:nc_photos/entity/person.dart';
|
||||
|
@ -126,7 +127,8 @@ class HomeSearchSuggestionBlocFailure extends HomeSearchSuggestionBlocState {
|
|||
@npLog
|
||||
class HomeSearchSuggestionBloc
|
||||
extends Bloc<HomeSearchSuggestionBlocEvent, HomeSearchSuggestionBlocState> {
|
||||
HomeSearchSuggestionBloc(this.account, this.collectionsController)
|
||||
HomeSearchSuggestionBloc(
|
||||
this.account, this.collectionsController, this.serverController)
|
||||
: super(const HomeSearchSuggestionBlocInit()) {
|
||||
final c = KiwiContainer().resolve<DiContainer>();
|
||||
assert(require(c));
|
||||
|
@ -194,7 +196,9 @@ class HomeSearchSuggestionBloc
|
|||
.map((e) => e.collection)
|
||||
.toList();
|
||||
if (collections.isEmpty) {
|
||||
collections = await ListCollection(_c)(account).last;
|
||||
collections = await ListCollection(_c,
|
||||
serverController: serverController)(account)
|
||||
.last;
|
||||
}
|
||||
product.addAll(collections.map(_CollectionSearcheable.new));
|
||||
_log.info(
|
||||
|
@ -247,6 +251,7 @@ class HomeSearchSuggestionBloc
|
|||
|
||||
final Account account;
|
||||
final CollectionsController collectionsController;
|
||||
final ServerController serverController;
|
||||
late final DiContainer _c;
|
||||
|
||||
final _search = Woozy<_Searcheable>(limit: 10);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/controller/collections_controller.dart';
|
||||
import 'package:nc_photos/controller/server_controller.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
|
||||
class AccountController {
|
||||
|
@ -8,6 +9,7 @@ class AccountController {
|
|||
_account = account;
|
||||
_collectionsController?.dispose();
|
||||
_collectionsController = null;
|
||||
_serverController = null;
|
||||
}
|
||||
|
||||
Account get account => _account!;
|
||||
|
@ -16,8 +18,15 @@ class AccountController {
|
|||
_collectionsController ??= CollectionsController(
|
||||
KiwiContainer().resolve<DiContainer>(),
|
||||
account: _account!,
|
||||
serverController: serverController,
|
||||
);
|
||||
|
||||
ServerController get serverController =>
|
||||
_serverController ??= ServerController(
|
||||
account: _account!,
|
||||
);
|
||||
|
||||
Account? _account;
|
||||
CollectionsController? _collectionsController;
|
||||
ServerController? _serverController;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:logging/logging.dart';
|
|||
import 'package:mutex/mutex.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/controller/collection_items_controller.dart';
|
||||
import 'package:nc_photos/controller/server_controller.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/collection.dart';
|
||||
import 'package:nc_photos/entity/collection/util.dart';
|
||||
|
@ -64,6 +65,7 @@ class CollectionsController {
|
|||
CollectionsController(
|
||||
this._c, {
|
||||
required this.account,
|
||||
required this.serverController,
|
||||
});
|
||||
|
||||
void dispose() {
|
||||
|
@ -264,7 +266,7 @@ class CollectionsController {
|
|||
hasNext: false,
|
||||
);
|
||||
final completer = Completer();
|
||||
ListCollection(_c)(account).listen(
|
||||
ListCollection(_c, serverController: serverController)(account).listen(
|
||||
(c) {
|
||||
lastData = CollectionStreamEvent(
|
||||
data: _prepareDataFor(c),
|
||||
|
@ -325,6 +327,7 @@ class CollectionsController {
|
|||
|
||||
final DiContainer _c;
|
||||
final Account account;
|
||||
final ServerController serverController;
|
||||
|
||||
var _isDataStreamInited = false;
|
||||
final _dataStreamController = BehaviorSubject.seeded(
|
||||
|
|
49
app/lib/controller/server_controller.dart
Normal file
49
app/lib/controller/server_controller.dart
Normal file
|
@ -0,0 +1,49 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/api/entity_converter.dart';
|
||||
import 'package:nc_photos/entity/server_status.dart';
|
||||
import 'package:nc_photos/np_api_util.dart';
|
||||
import 'package:np_api/np_api.dart' as api;
|
||||
import 'package:np_codegen/np_codegen.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
part 'server_controller.g.dart';
|
||||
|
||||
@npLog
|
||||
class ServerController {
|
||||
ServerController({
|
||||
required this.account,
|
||||
});
|
||||
|
||||
ValueStream<ServerStatus> get status {
|
||||
if (!_statusStreamContorller.hasValue) {
|
||||
unawaited(_load());
|
||||
}
|
||||
return _statusStreamContorller.stream;
|
||||
}
|
||||
|
||||
Future<void> _load() => _getStatus();
|
||||
|
||||
Future<void> _getStatus() async {
|
||||
try {
|
||||
final response = await ApiUtil.fromAccount(account).status().get();
|
||||
if (!response.isGood) {
|
||||
_log.severe("[_getStatus] Failed requesting server: $response");
|
||||
return;
|
||||
}
|
||||
final apiStatus = await api.StatusParser().parse(response.body);
|
||||
final status = ApiStatusConverter.fromApi(apiStatus);
|
||||
_log.info("[_getStatus] Server status: $status");
|
||||
_statusStreamContorller.add(status);
|
||||
} catch (e, stackTrace) {
|
||||
_log.severe("[_getStatus] Failed while get", e, stackTrace);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final Account account;
|
||||
|
||||
final _statusStreamContorller = BehaviorSubject<ServerStatus>();
|
||||
}
|
14
app/lib/controller/server_controller.g.dart
Normal file
14
app/lib/controller/server_controller.g.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'server_controller.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// NpLogGenerator
|
||||
// **************************************************************************
|
||||
|
||||
extension _$ServerControllerNpLog on ServerController {
|
||||
// ignore: unused_element
|
||||
Logger get _log => log;
|
||||
|
||||
static final log = Logger("controller.server_controller.ServerController");
|
||||
}
|
24
app/lib/entity/server_status.dart
Normal file
24
app/lib/entity/server_status.dart
Normal file
|
@ -0,0 +1,24 @@
|
|||
import 'package:to_string/to_string.dart';
|
||||
|
||||
part 'server_status.g.dart';
|
||||
|
||||
@toString
|
||||
class ServerStatus {
|
||||
const ServerStatus({
|
||||
required this.versionRaw,
|
||||
required this.versionName,
|
||||
required this.productName,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() => _$toString();
|
||||
|
||||
final String versionRaw;
|
||||
final String versionName;
|
||||
final String productName;
|
||||
}
|
||||
|
||||
extension ServerStatusExtension on ServerStatus {
|
||||
List<int> get versionNumber => versionRaw.split(".").map(int.parse).toList();
|
||||
int get majorVersion => versionNumber[0];
|
||||
}
|
14
app/lib/entity/server_status.g.dart
Normal file
14
app/lib/entity/server_status.g.dart
Normal file
|
@ -0,0 +1,14 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'server_status.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// ToStringGenerator
|
||||
// **************************************************************************
|
||||
|
||||
extension _$ServerStatusToString on ServerStatus {
|
||||
String _$toString() {
|
||||
// ignore: unnecessary_string_interpolations
|
||||
return "ServerStatus {versionRaw: $versionRaw, versionName: $versionName, productName: $productName}";
|
||||
}
|
||||
}
|
|
@ -1,16 +1,21 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/controller/server_controller.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/collection.dart';
|
||||
import 'package:nc_photos/entity/collection/builder.dart';
|
||||
import 'package:nc_photos/entity/nc_album.dart';
|
||||
import 'package:nc_photos/entity/server_status.dart';
|
||||
import 'package:nc_photos/use_case/album/list_album2.dart';
|
||||
import 'package:nc_photos/use_case/nc_album/list_nc_album.dart';
|
||||
|
||||
class ListCollection {
|
||||
ListCollection(this._c) : assert(require(_c));
|
||||
ListCollection(
|
||||
this._c, {
|
||||
required this.serverController,
|
||||
}) : assert(require(_c));
|
||||
|
||||
static bool require(DiContainer c) =>
|
||||
DiContainer.has(c, DiType.albumRepo2) &&
|
||||
|
@ -51,23 +56,29 @@ class ListCollection {
|
|||
onDone();
|
||||
},
|
||||
);
|
||||
ListNcAlbum(_c)(account).listen(
|
||||
(event) {
|
||||
ncAlbums = event;
|
||||
notify();
|
||||
},
|
||||
onDone: () {
|
||||
isNcAlbumDone = true;
|
||||
onDone();
|
||||
},
|
||||
onError: (e, stackTrace) {
|
||||
controller.addError(e, stackTrace);
|
||||
isNcAlbumDone = true;
|
||||
onDone();
|
||||
},
|
||||
);
|
||||
if (serverController.status.hasValue &&
|
||||
serverController.status.value.majorVersion < 25) {
|
||||
isNcAlbumDone = true;
|
||||
} else {
|
||||
ListNcAlbum(_c)(account).listen(
|
||||
(event) {
|
||||
ncAlbums = event;
|
||||
notify();
|
||||
},
|
||||
onDone: () {
|
||||
isNcAlbumDone = true;
|
||||
onDone();
|
||||
},
|
||||
onError: (e, stackTrace) {
|
||||
controller.addError(e, stackTrace);
|
||||
isNcAlbumDone = true;
|
||||
onDone();
|
||||
},
|
||||
);
|
||||
}
|
||||
return controller.stream;
|
||||
}
|
||||
|
||||
final DiContainer _c;
|
||||
final ServerController serverController;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/account.dart';
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/controller/account_controller.dart';
|
||||
import 'package:nc_photos/di_container.dart';
|
||||
import 'package:nc_photos/entity/album.dart';
|
||||
import 'package:nc_photos/entity/album/data_source.dart';
|
||||
|
@ -64,6 +68,16 @@ class _HomeState extends State<Home> with TickerProviderStateMixin {
|
|||
});
|
||||
}
|
||||
_animationController.value = 1;
|
||||
|
||||
// call once to pre-cache the value
|
||||
unawaited(context
|
||||
.read<AccountController>()
|
||||
.serverController
|
||||
.status
|
||||
.first
|
||||
.then((value) {
|
||||
_log.info("Server status: $value");
|
||||
}));
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -79,6 +79,7 @@ class _HomeSearchSuggestionState extends State<HomeSearchSuggestion>
|
|||
_bloc = (widget.controller._bloc ??= HomeSearchSuggestionBloc(
|
||||
widget.account,
|
||||
context.read<AccountController>().collectionsController,
|
||||
context.read<AccountController>().serverController,
|
||||
));
|
||||
if (_bloc.state is! HomeSearchSuggestionBlocInit) {
|
||||
// process the current state
|
||||
|
|
|
@ -8,6 +8,7 @@ export 'src/entity/nc_album_parser.dart';
|
|||
export 'src/entity/person_parser.dart';
|
||||
export 'src/entity/share_parser.dart';
|
||||
export 'src/entity/sharee_parser.dart';
|
||||
export 'src/entity/status_parser.dart';
|
||||
export 'src/entity/tag_parser.dart';
|
||||
export 'src/entity/tagged_file_parser.dart';
|
||||
export 'src/type.dart';
|
||||
|
|
|
@ -27,6 +27,8 @@ class Api {
|
|||
|
||||
ApiPhotos photos(String userId) => ApiPhotos(this, userId);
|
||||
|
||||
ApiStatus status() => ApiStatus(this);
|
||||
|
||||
ApiSystemtags systemtags() => ApiSystemtags(this);
|
||||
|
||||
ApiSystemtagsRelations systemtagsRelations() => ApiSystemtagsRelations(this);
|
||||
|
|
|
@ -299,6 +299,7 @@ class Status with EquatableMixin {
|
|||
const Status({
|
||||
required this.version,
|
||||
required this.versionString,
|
||||
required this.productName,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -308,10 +309,12 @@ class Status with EquatableMixin {
|
|||
List<Object?> get props => [
|
||||
version,
|
||||
versionString,
|
||||
productName,
|
||||
];
|
||||
|
||||
final String version;
|
||||
final String versionString;
|
||||
final String productName;
|
||||
}
|
||||
|
||||
@toString
|
||||
|
|
|
@ -13,6 +13,7 @@ class StatusParser {
|
|||
return Status(
|
||||
version: json["version"],
|
||||
versionString: json["versionstring"],
|
||||
productName: json["productname"],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
34
np_api/test/entity/status_parser_test.dart
Normal file
34
np_api/test/entity/status_parser_test.dart
Normal file
|
@ -0,0 +1,34 @@
|
|||
import 'package:np_api/np_api.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group("StatusParser", () {
|
||||
group("parse", () {
|
||||
test("Nextcloud 25", _nextcloud25);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _nextcloud25() async {
|
||||
const json = """
|
||||
{
|
||||
"installed": true,
|
||||
"maintenance": false,
|
||||
"needsDbUpgrade": false,
|
||||
"version": "25.0.2.3",
|
||||
"versionstring": "25.0.2",
|
||||
"edition": "",
|
||||
"productname": "Nextcloud",
|
||||
"extendedSupport": false
|
||||
}
|
||||
""";
|
||||
final results = await StatusParser().parse(json);
|
||||
expect(
|
||||
results,
|
||||
const Status(
|
||||
version: "25.0.2.3",
|
||||
versionString: "25.0.2",
|
||||
productName: "Nextcloud",
|
||||
),
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue