Skip to content

Commit

Permalink
Merge pull request #886 from nextcloud/refactor/neon
Browse files Browse the repository at this point in the history
Refactor/neon
  • Loading branch information
Leptopoda authored Oct 16, 2023
2 parents ce78e45 + aade4c3 commit 66bfc32
Show file tree
Hide file tree
Showing 18 changed files with 106 additions and 144 deletions.
7 changes: 3 additions & 4 deletions packages/neon/neon/lib/l10n/en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,15 @@
"errorNoCompatibleNextcloudAppsFound": "No compatible Nextcloud apps could be found.\nWe are working hard to implement more and more apps!",
"errorServerInMaintenanceMode": "The server is in maintenance mode. Please try again later or contact the server admin.",
"errorMissingPermission": "Permission for {name} is missing",
"@errorMissingPermission" : {
"@errorMissingPermission": {
"placeholders": {
"name": {
"type": "String"
}
}
},
"errorUnsupportedAppVersions": "Sorry, the version of the following apps on your Nextcloud instance are not supported. \n {names} \n Please contact your administrator to resolve the issues.",
"@errorUnsupportedAppVersions" : {
"@errorUnsupportedAppVersions": {
"placeholders": {
"names": {
"type": "String"
Expand All @@ -70,7 +70,7 @@
"errorInvalidURL": "Invalid URL provided",
"errorInvalidQRcode": "Invalid QR-Code provided",
"errorRouteNotFound": "Route not found: {route}",
"@errorRouteNotFound" : {
"@errorRouteNotFound": {
"placeholders": {
"route": {
"type": "String"
Expand Down Expand Up @@ -152,7 +152,6 @@
"globalOptionsNavigationMode": "Navigation mode",
"globalOptionsNavigationModeDrawer": "Drawer",
"globalOptionsNavigationModeDrawerAlwaysVisible": "Drawer always visible",
"globalOptionsNavigationModeQuickBar": "Quick bar",
"accountOptionsRemove": "Remove account",
"accountOptionsRemoveConfirm": "Are you sure you want to remove the account {id}?",
"@accountOptionsRemoveConfirm": {
Expand Down
6 changes: 0 additions & 6 deletions packages/neon/neon/lib/l10n/localizations.dart
Original file line number Diff line number Diff line change
Expand Up @@ -635,12 +635,6 @@ abstract class AppLocalizations {
/// **'Drawer always visible'**
String get globalOptionsNavigationModeDrawerAlwaysVisible;

/// No description provided for @globalOptionsNavigationModeQuickBar.
///
/// In en, this message translates to:
/// **'Quick bar'**
String get globalOptionsNavigationModeQuickBar;

/// No description provided for @accountOptionsRemove.
///
/// In en, this message translates to:
Expand Down
3 changes: 0 additions & 3 deletions packages/neon/neon/lib/l10n/localizations_en.dart
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,6 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get globalOptionsNavigationModeDrawerAlwaysVisible => 'Drawer always visible';

@override
String get globalOptionsNavigationModeQuickBar => 'Quick bar';

@override
String get accountOptionsRemove => 'Remove account';

Expand Down
12 changes: 4 additions & 8 deletions packages/neon/neon/lib/src/blocs/apps.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ abstract interface class AppsBlocEvents {

@internal
abstract interface class AppsBlocStates {
BehaviorSubject<Result<List<core.NavigationEntry>>> get apps;

BehaviorSubject<Result<Iterable<AppImplementation>>> get appImplementations;

BehaviorSubject<Result<NotificationsAppInterface?>> get notificationsAppImplementation;
Expand All @@ -48,7 +46,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
this._account,
this._allAppImplementations,
) {
apps.listen((final result) {
_apps.listen((final result) {
appImplementations
.add(result.transform((final data) => _filteredAppImplementations(data.map((final a) => a.id))));
});
Expand Down Expand Up @@ -162,10 +160,11 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
final AccountsBloc _accountsBloc;
final Account _account;
final Iterable<AppImplementation> _allAppImplementations;
final _apps = BehaviorSubject<Result<List<core.NavigationEntry>>>();

@override
void dispose() {
unawaited(apps.close());
unawaited(_apps.close());
unawaited(appImplementations.close());
unawaited(notificationsAppImplementation.close());
unawaited(activeApp.close());
Expand All @@ -182,9 +181,6 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
BehaviorSubject<Result<Iterable<AppImplementation<Bloc, NextcloudAppOptions>>>> appImplementations =
BehaviorSubject();

@override
BehaviorSubject<Result<List<core.NavigationEntry>>> apps = BehaviorSubject();

@override
BehaviorSubject<Result<NotificationsAppInterface?>> notificationsAppImplementation = BehaviorSubject();

Expand All @@ -199,7 +195,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
await RequestManager.instance.wrapNextcloud(
_account.id,
'apps-apps',
apps,
_apps,
_account.client.core.navigation.getAppsNavigationRaw(),
(final response) => response.body.ocs.data.toList(),
);
Expand Down
10 changes: 4 additions & 6 deletions packages/neon/neon/lib/src/blocs/push_notifications.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
}

final AccountsBloc _accountsBloc;
late final _storage = const AppStorage(StorageKeys.notifications);
late final _storage = const AppStorage(StorageKeys.lastEndpoint);
final GlobalOptions _globalOptions;

StreamSubscription<List<Account>>? _accountsListener;
Expand All @@ -46,8 +46,6 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
_globalOptions.pushNotificationsEnabled.removeListener(_pushNotificationsEnabledListener);
}

String _keyLastEndpoint(final Account account) => 'last-endpoint-${account.id}';

Future<void> _pushNotificationsEnabledListener() async {
if (_globalOptions.pushNotificationsEnabled.value) {
await _setupUnifiedPush();
Expand All @@ -72,7 +70,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
return;
}

if (_storage.getString(_keyLastEndpoint(account)) == endpoint) {
if (_storage.getString(account.id) == endpoint) {
debugPrint('Endpoint not changed');
return;
}
Expand All @@ -85,7 +83,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
proxyServer: '$endpoint#', // This is a hack to make the Nextcloud server directly push to the endpoint
);

await _storage.setString(_keyLastEndpoint(account), endpoint);
await _storage.setString(account.id, endpoint);

debugPrint(
'Account $instance registered for push notifications ${json.encode(subscription.body.ocs.data.toJson())}',
Expand Down Expand Up @@ -117,7 +115,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
try {
await account.client.notifications.push.removeDevice();
await UnifiedPush.unregister(account.id);
await _storage.remove(_keyLastEndpoint(account));
await _storage.remove(account.id);
} catch (e) {
debugPrint('Failed to unregister device: $e');
}
Expand Down
2 changes: 1 addition & 1 deletion packages/neon/neon/lib/src/blocs/user_statuses.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class UserStatusesBloc extends InteractiveBloc implements UserStatusesBlocEvents
var isAway = false;
if (NeonPlatform.instance.canUseWindowManager) {
final focused = await windowManager.isFocused();
final visible = await windowManager.isFocused();
final visible = await windowManager.isVisible();
isAway = !focused || !visible;
}
try {
Expand Down
4 changes: 1 addition & 3 deletions packages/neon/neon/lib/src/models/app_implementation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@ import 'package:vector_graphics/vector_graphics.dart';

@immutable
abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions> implements Disposable {
AppImplementation();

String get id;
LocalizationsDelegate<Object> get localizationsDelegate;
List<Locale> get supportedLocales;
Iterable<Locale> get supportedLocales;

String nameFromLocalization(final AppLocalizations localizations) => localizations.appImplementationName(id);
String name(final BuildContext context) => nameFromLocalization(AppLocalizations.of(context));
Expand Down
10 changes: 5 additions & 5 deletions packages/neon/neon/lib/src/settings/models/storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,23 +102,23 @@ final class SingleValueStorage {
@internal
final class AppStorage implements SettingsStorage {
const AppStorage(
this.key, [
this.groupKey, [
this.suffix,
]);

final StorageKeys key;
final StorageKeys groupKey;

final String? suffix;

String get id => suffix ?? key.value;
String get id => suffix ?? groupKey.value;

@visibleForTesting
String formatKey(final String key) {
if (suffix != null) {
return '${this.key.value}-$suffix-$key';
return '${groupKey.value}-$suffix-$key';
}

return '${this.key.value}-$key';
return '${groupKey.value}-$key';
}

bool containsKey(final String key) => NeonStorage.database.containsKey(formatKey(key));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@ import 'package:neon/src/widgets/account_tile.dart';
class AccountSettingsTile extends SettingsTile {
const AccountSettingsTile({
required this.account,
this.color,
this.trailing,
this.onTap,
super.key,
});

final Account account;
final Color? color;

final Widget? trailing;
final GestureTapCallback? onTap;

@override
Widget build(final BuildContext context) => NeonAccountTile(
account: account,
color: color,
trailing: trailing,
onTap: onTap,
);
Expand Down
5 changes: 1 addition & 4 deletions packages/neon/neon/lib/src/utils/account_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ class AccountSpecificOptions extends OptionsCollection {

initialApp.values = {
null: (final context) => AppLocalizations.of(context).accountOptionsAutomatic,
for (final app in result.requireData) ...{
app.id: app.name,
},
};
}..addEntries(result.requireData.map((final app) => MapEntry(app.id, app.name)));
});
}

Expand Down
42 changes: 20 additions & 22 deletions packages/neon/neon/lib/src/utils/global_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class GlobalOptions extends OptionsCollection {
void _rememberLastUsedAccountListener() {
initialAccount.enabled = !rememberLastUsedAccount.value;
if (rememberLastUsedAccount.value) {
initialAccount.value = null;
initialAccount.reset();
} else {
// Only override the initial account if there already has been a value,
// which means it's not the initial emit from rememberLastUsedAccount
Expand All @@ -44,7 +44,7 @@ class GlobalOptions extends OptionsCollection {
pushNotificationsEnabled.value = false;
}
} else {
pushNotificationsDistributor.value = null;
pushNotificationsDistributor.reset();
}
}

Expand Down Expand Up @@ -91,26 +91,29 @@ class GlobalOptions extends OptionsCollection {
}

void updateAccounts(final List<Account> accounts) {
initialAccount.values = {
for (final account in accounts) account.id: (final context) => account.humanReadableID,
};
initialAccount.values = Map.fromEntries(
accounts.map(
(final account) => MapEntry(account.id, (final context) => account.humanReadableID),
),
);

if (accounts.tryFind(initialAccount.value) == null) {
if (!initialAccount.values.containsKey(initialAccount.value)) {
initialAccount.reset();
}
}

Future<void> updateDistributors(final List<String> distributors) async {
pushNotificationsDistributor.values = {
for (final distributor in distributors) ...{
distributor: _distributorsMap[distributor] ?? (final _) => distributor,
},
};
void updateDistributors(final List<String> distributors) {
pushNotificationsDistributor.values = Map.fromEntries(
distributors.map(
(final distributor) => MapEntry(distributor, _distributorsMap[distributor] ?? (final _) => distributor),
),
);

final allowed = distributors.isNotEmpty;
final allowed = pushNotificationsDistributor.values.containsKey(pushNotificationsDistributor.value);
pushNotificationsEnabled.enabled = allowed;
if (!allowed) {
pushNotificationsEnabled.value = false;
pushNotificationsDistributor.reset();
pushNotificationsEnabled.reset();
}
}

Expand All @@ -128,7 +131,7 @@ class GlobalOptions extends OptionsCollection {

late final themeOLEDAsDark = ToggleOption(
storage: storage,
key: GlobalOptionKeys.themeOledAsDark,
key: GlobalOptionKeys.themeOLEDAsDark,
label: (final context) => AppLocalizations.of(context).globalOptionsThemeOLEDAsDark,
defaultValue: false,
);
Expand Down Expand Up @@ -209,20 +212,17 @@ class GlobalOptions extends OptionsCollection {
defaultValue: Platform.isAndroid || Platform.isIOS ? NavigationMode.drawer : NavigationMode.drawerAlwaysVisible,
values: {
NavigationMode.drawer: (final context) => AppLocalizations.of(context).globalOptionsNavigationModeDrawer,
if (!Platform.isAndroid && !Platform.isIOS) ...{
if (!Platform.isAndroid && !Platform.isIOS)
NavigationMode.drawerAlwaysVisible: (final context) =>
AppLocalizations.of(context).globalOptionsNavigationModeDrawerAlwaysVisible,
},
// ignore: deprecated_member_use_from_same_package
NavigationMode.quickBar: (final context) => AppLocalizations.of(context).globalOptionsNavigationModeQuickBar,
},
);
}

@internal
enum GlobalOptionKeys implements Storable {
themeMode._('theme-mode'),
themeOledAsDark._('theme-oled-as-dark'),
themeOLEDAsDark._('theme-oled-as-dark'),
themeKeepOriginalAccentColor._('theme-keep-original-accent-color'),
pushNotificationsEnabled._('push-notifications-enabled'),
pushNotificationsDistributor._('push-notifications-distributor'),
Expand All @@ -244,6 +244,4 @@ enum GlobalOptionKeys implements Storable {
enum NavigationMode {
drawer,
drawerAlwaysVisible,
@Deprecated("The new design won't use this anymore")
quickBar,
}
14 changes: 7 additions & 7 deletions packages/neon/neon/lib/src/utils/global_popups.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class GlobalPopups {
}
_subscriptions.clear();
_registered = false;
instance = null;
}

void register(final BuildContext context) {
Expand All @@ -42,12 +43,13 @@ class GlobalPopups {
return;
}

_registered = true;

final globalOptions = NeonProvider.of<GlobalOptions>(context);
final firstLaunchBloc = NeonProvider.of<FirstLaunchBloc>(context);
final nextPushBloc = NeonProvider.of<NextPushBloc>(context);

_subscriptions.addAll([
if (NeonPlatform.instance.canUsePushNotifications) ...[
if (NeonPlatform.instance.canUsePushNotifications) {
_subscriptions.addAll([
firstLaunchBloc.onFirstLaunch.listen((final _) {
assert(context.mounted, 'Context should be mounted');
if (!globalOptions.pushNotificationsEnabled.enabled) {
Expand Down Expand Up @@ -98,9 +100,7 @@ class GlobalPopups {
),
);
}),
],
]);

_registered = true;
]);
}
}
}
Loading

0 comments on commit 66bfc32

Please sign in to comment.