You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
109 lines
2.8 KiB
109 lines
2.8 KiB
3 years ago
|
import 'dart:convert';
|
||
|
|
||
|
import 'package:crypto/crypto.dart';
|
||
|
import 'package:json_annotation/json_annotation.dart';
|
||
3 years ago
|
import 'package:neon/src/neon.dart';
|
||
3 years ago
|
import 'package:nextcloud/nextcloud.dart';
|
||
|
import 'package:rxdart/rxdart.dart';
|
||
|
import 'package:settings/settings.dart';
|
||
|
|
||
|
part 'account.g.dart';
|
||
|
|
||
3 years ago
|
String userAgentOverride() => 'Neon ${Global.packageInfo.version}+${Global.packageInfo.buildNumber}';
|
||
3 years ago
|
|
||
|
@JsonSerializable()
|
||
|
class Account {
|
||
|
Account({
|
||
|
required this.serverURL,
|
||
|
required this.username,
|
||
|
this.password,
|
||
|
this.appPassword,
|
||
|
}) : assert(
|
||
|
(password != null && appPassword == null) || (password == null && appPassword != null),
|
||
|
'Either password or appPassword has to be set',
|
||
|
);
|
||
|
|
||
|
factory Account.fromJson(final Map<String, dynamic> json) => _$AccountFromJson(json);
|
||
|
Map<String, dynamic> toJson() => _$AccountToJson(this);
|
||
|
|
||
|
final String serverURL;
|
||
|
final String username;
|
||
|
final String? password;
|
||
|
final String? appPassword;
|
||
|
|
||
|
@override
|
||
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||
|
bool operator ==(final Object other) =>
|
||
|
other is Account &&
|
||
|
other.serverURL == serverURL &&
|
||
|
other.username == username &&
|
||
|
other.password == password &&
|
||
|
other.appPassword == appPassword;
|
||
|
|
||
|
@override
|
||
|
// ignore: avoid_equals_and_hash_code_on_mutable_classes
|
||
|
int get hashCode => serverURL.hashCode + username.hashCode;
|
||
|
|
||
|
String get id => client.id;
|
||
|
|
||
|
NextcloudClient? _client;
|
||
|
|
||
|
NextcloudClient get client => _client ??= NextcloudClient(
|
||
|
serverURL,
|
||
|
username: username,
|
||
|
password: password ?? appPassword,
|
||
3 years ago
|
userAgentOverride: userAgentOverride(),
|
||
3 years ago
|
);
|
||
|
}
|
||
|
|
||
|
Map<String, String> _idCache = {};
|
||
|
|
||
|
extension NextcloudClientID on NextcloudClient {
|
||
|
String get id {
|
||
|
final key = '$username@$baseURL';
|
||
|
if (_idCache[key] != null) {
|
||
|
return _idCache[key]!;
|
||
|
}
|
||
|
return _idCache[key] = sha1.convert(utf8.encode(key)).toString();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class AccountSpecificOptions {
|
||
|
AccountSpecificOptions(this._storage);
|
||
|
|
||
|
final Storage _storage;
|
||
|
final _appIDsSubject = BehaviorSubject<Map<String?, LabelBuilder>>();
|
||
|
|
||
|
late final List<Option> options = [
|
||
|
initialApp,
|
||
|
];
|
||
|
|
||
|
void updateApps(final List<NextcloudApp> apps) {
|
||
|
if (apps.isEmpty) {
|
||
|
return;
|
||
|
}
|
||
|
_appIDsSubject.add({
|
||
|
null: (final context) => AppLocalizations.of(context).accountOptionsAutomatic,
|
||
|
for (final app in apps) ...{
|
||
|
app.id: (final _) => app.name!,
|
||
|
},
|
||
|
});
|
||
|
}
|
||
|
|
||
|
void dispose() {
|
||
|
// ignore: discarded_futures
|
||
|
_appIDsSubject.close();
|
||
|
for (final option in options) {
|
||
|
option.dispose();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
late final initialApp = SelectOption<String?>(
|
||
|
storage: _storage,
|
||
|
key: 'initial-app',
|
||
|
label: (final context) => AppLocalizations.of(context).accountOptionsInitialApp,
|
||
|
defaultValue: BehaviorSubject.seeded(null),
|
||
|
values: _appIDsSubject,
|
||
|
);
|
||
|
}
|