A framework for building convergent cross-platform Nextcloud clients using Flutter.
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.

120 lines
3.1 KiB

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