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.
119 lines
3.1 KiB
119 lines
3.1 KiB
import 'dart:convert'; |
|
|
|
import 'package:crypto/crypto.dart'; |
|
import 'package:json_annotation/json_annotation.dart'; |
|
import 'package:neon/l10n/localizations.dart'; |
|
import 'package:neon/src/neon.dart'; |
|
import 'package:nextcloud/nextcloud.dart'; |
|
import 'package:package_info_plus/package_info_plus.dart'; |
|
import 'package:rxdart/rxdart.dart'; |
|
import 'package:settings/settings.dart'; |
|
|
|
part 'account.g.dart'; |
|
|
|
String userAgent(PackageInfo packageInfo) => 'Neon ${packageInfo.version}+${packageInfo.buildNumber}'; |
|
|
|
@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; |
|
|
|
void setupClient(PackageInfo packageInfo) { |
|
_client ??= NextcloudClient( |
|
serverURL, |
|
username: username, |
|
password: appPassword ?? password, |
|
userAgentOverride: userAgent(packageInfo), |
|
); |
|
} |
|
|
|
NextcloudClient get client { |
|
if (_client == null) { |
|
throw Exception('You need to call setupClient() first'); |
|
} |
|
|
|
return _client!; |
|
} |
|
} |
|
|
|
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<AppImplementation> apps) { |
|
if (apps.isEmpty) { |
|
return; |
|
} |
|
_appIDsSubject.add({ |
|
null: (final context) => AppLocalizations.of(context).accountOptionsAutomatic, |
|
for (final app in apps) ...{ |
|
app.id: app.name, |
|
}, |
|
}); |
|
} |
|
|
|
void dispose() { |
|
_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, |
|
); |
|
}
|
|
|