Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HomeView background setting and displaying (#123) #129

Merged
merged 21 commits into from
Sep 26, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/l10n/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ btn_cancel = Cancel
btn_call_video_on_desc =
Turn
video on
btn_change = Change
btn_change_contact_name = Rename contact
btn_change_password = Change password
btn_close = Close
Expand Down Expand Up @@ -151,6 +152,8 @@ btn_logout = Logout
btn_media_settings = Media settings
btn_next = Next
btn_ok = Ok
btn_personalize = Personalization
btn_remove = Remove
btn_reply = Reply
btn_resend_code = Resend confirmation code
btn_resend_message = Resend message
Expand Down Expand Up @@ -425,6 +428,7 @@ label_read_by = Read by
label_recover_account = Access recovery
label_recovery_code = Recovery code
label_repeat_password = Repeat password
label_personalization = Personalization
label_search = Search
label_search_hint = Search by Gapopa ID, login or name
label_search_not_found = Not found
Expand Down
4 changes: 4 additions & 0 deletions assets/l10n/ru-RU.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ btn_cancel = Отмена
btn_call_video_on_desc =
Включить
камеру
btn_change = Сменить
btn_change_contact_name = Переименовать контакт
btn_change_password = Сменить пароль
btn_close = Закрыть
Expand Down Expand Up @@ -151,6 +152,8 @@ btn_logout = Выйти
btn_media_settings = Настройки медиа
btn_next = Далее
btn_ok = Ок
btn_personalize = Персонализация
btn_remove = Удалить
btn_reply = Ответить
btn_resend_code = Отправить код ещё раз
btn_resend_message = Повторить отправку
Expand Down Expand Up @@ -439,6 +442,7 @@ label_read_by = Прочитано
label_recover_account = Восстановление доступа
label_recovery_code = Код восстановления
label_repeat_password = Повторите пароль
label_personalization = Персонализация
label_search = Поиск
label_search_hint = Поиск по Gapopa ID, логину или имени
label_search_not_found = Ничего не найдено
Expand Down
1 change: 1 addition & 0 deletions lib/domain/model_type_id.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,5 @@ class ModelTypeId {
static const nativeFile = 77;
static const localAttachment = 78;
static const mediaType = 79;
static const hiveBackground = 80;
}
8 changes: 8 additions & 0 deletions lib/domain/repository/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// along with this program. If not, see
// <https://www.gnu.org/licenses/agpl-3.0.html>.

import 'dart:typed_data';

import 'package:get/get.dart';

import '/domain/model/application_settings.dart';
Expand All @@ -27,6 +29,9 @@ abstract class AbstractSettingsRepository {
/// Returns the stored [ApplicationSettings].
Rx<ApplicationSettings?> get applicationSettings;

/// Returns the stored [Uint8List] of the background.
Rx<Uint8List?> get background;

/// Clears the stored settings.
Future<void> clearCache();

Expand All @@ -50,4 +55,7 @@ abstract class AbstractSettingsRepository {

/// Sets the [ApplicationSettings.sideBarWidth] value.
Future<void> setSideBarWidth(double width);

/// Sets the [background] value.
Future<void> setBackground(Uint8List? bytes);
}
57 changes: 57 additions & 0 deletions lib/provider/hive/background.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright © 2022 IT ENGINEERING MANAGEMENT INC, <https://github.com/team113>
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU Affero General Public License v3.0 as published by the
// Free Software Foundation, either version 3 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License v3.0 for
// more details.
//
// You should have received a copy of the GNU Affero General Public License v3.0
// along with this program. If not, see
// <https://www.gnu.org/licenses/agpl-3.0.html>.

import 'dart:typed_data';

import 'package:hive_flutter/hive_flutter.dart';

import '/domain/model_type_id.dart';
import 'base.dart';

part 'background.g.dart';

/// [Hive] storage for [HiveBackground].
class BackgroundHiveProvider extends HiveBaseProvider<HiveBackground> {
@override
Stream<BoxEvent> get boxEvents => box.watch();

@override
String get boxName => 'background';

@override
void registerAdapters() {
Hive.maybeRegisterAdapter(HiveBackgroundAdapter());
}

/// Returns the stored [Uint8List] from [Hive].
Uint8List? get bytes => getSafe(0)?.bytes;

/// Saves the provided [Uint8List] to [Hive].
Future<void> set(Uint8List bytes) => putSafe(0, HiveBackground(bytes));

/// Deletes the stored [Uint8List].
Future<void> delete() => deleteSafe(0);
}

/// Persisted in [Hive] storage background's [Uint8List] value.
@HiveType(typeId: ModelTypeId.hiveBackground)
class HiveBackground extends HiveObject {
HiveBackground(this.bytes);

/// Persisted background itself.
@HiveField(0)
final Uint8List bytes;
}
12 changes: 10 additions & 2 deletions lib/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import 'domain/service/user.dart';
import 'l10n/l10n.dart';
import 'provider/gql/graphql.dart';
import 'provider/hive/application_settings.dart';
import 'provider/hive/background.dart';
import 'provider/hive/chat.dart';
import 'provider/hive/contact.dart';
import 'provider/hive/gallery_item.dart';
Expand Down Expand Up @@ -77,6 +78,7 @@ class Routes {
static const home = '/';
static const me = '/me';
static const menu = '/menu';
static const personalization = '/personalization';
static const settings = '/settings';
static const settingsMedia = '/settings/media';
static const user = '/user';
Expand Down Expand Up @@ -386,11 +388,12 @@ class AppRouterDelegate extends RouterDelegate<RouteConfiguration>
deps.put(ContactHiveProvider()).init(userId: me),
deps.put(MediaSettingsHiveProvider()).init(userId: me),
deps.put(ApplicationSettingsHiveProvider()).init(userId: me),
deps.put(BackgroundHiveProvider()).init(userId: me),
]);

AbstractSettingsRepository settingsRepository =
deps.put<AbstractSettingsRepository>(
SettingsRepository(Get.find(), Get.find()),
SettingsRepository(Get.find(), Get.find(), Get.find()),
);

// Should be initialized before any [L10n]-dependant entities as
Expand Down Expand Up @@ -470,11 +473,12 @@ class AppRouterDelegate extends RouterDelegate<RouteConfiguration>
deps.put(ContactHiveProvider()).init(userId: me),
deps.put(MediaSettingsHiveProvider()).init(userId: me),
deps.put(ApplicationSettingsHiveProvider()).init(userId: me),
deps.put(BackgroundHiveProvider()).init(userId: me),
]);

AbstractSettingsRepository settingsRepository =
deps.put<AbstractSettingsRepository>(
SettingsRepository(Get.find(), Get.find()),
SettingsRepository(Get.find(), Get.find(), Get.find()),
);

// Should be initialized before any [L10n]-dependant entities as
Expand Down Expand Up @@ -564,6 +568,7 @@ class AppRouterDelegate extends RouterDelegate<RouteConfiguration>
_state.route == Routes.me ||
_state.route == Routes.settings ||
_state.route == Routes.settingsMedia ||
_state.route == Routes.personalization ||
_state.route == Routes.home) {
_updateTabTitle();
} else {
Expand Down Expand Up @@ -631,6 +636,9 @@ extension RouteLinks on RouterState {
/// Changes router location to the [Routes.settingsMedia] page.
void settingsMedia() => go(Routes.settingsMedia);

/// Changes router location to the [Routes.personalization] page.
void personalization() => go(Routes.personalization);
ArturRubets marked this conversation as resolved.
Show resolved Hide resolved

/// Changes router location to the [Routes.me] page.
void me() => go(Routes.me);

Expand Down
39 changes: 38 additions & 1 deletion lib/store/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// <https://www.gnu.org/licenses/agpl-3.0.html>.

import 'dart:async';
import 'dart:typed_data';

import 'package:get/get.dart';
import 'package:hive/hive.dart';
Expand All @@ -23,44 +24,62 @@ import '/domain/model/application_settings.dart';
import '/domain/model/media_settings.dart';
import '/domain/repository/settings.dart';
import '/provider/hive/application_settings.dart';
import '/provider/hive/background.dart';
import '/provider/hive/media_settings.dart';

/// Application settings repository.
class SettingsRepository extends DisposableInterface
implements AbstractSettingsRepository {
SettingsRepository(this._mediaLocal, this._settingsLocal);
SettingsRepository(
this._mediaLocal,
this._settingsLocal,
this._backgroundLocal,
);

@override
final Rx<MediaSettings?> mediaSettings = Rx(null);

@override
final Rx<ApplicationSettings?> applicationSettings = Rx(null);

@override
final Rx<Uint8List?> background = Rx(null);

/// [MediaSettings] local [Hive] storage.
final MediaSettingsHiveProvider _mediaLocal;

/// [ApplicationSettings] local [Hive] storage.
final ApplicationSettingsHiveProvider _settingsLocal;

/// [HiveBackground] local [Hive] storage.
final BackgroundHiveProvider _backgroundLocal;

/// [MediaSettingsHiveProvider.boxEvents] subscription.
StreamIterator? _mediaSubscription;

/// [ApplicationSettingsHiveProvider.boxEvents] subscription.
StreamIterator? _settingsSubscription;

/// [BackgroundHiveProvider.boxEvents] subscription.
StreamIterator? _backgroundSubscription;

@override
void onInit() {
mediaSettings.value = _mediaLocal.settings;
applicationSettings.value = _settingsLocal.settings;
background.value = _backgroundLocal.bytes;
_initMediaSubscription();
_initSettingsSubscription();
_initBackgroundSubscription();

super.onInit();
}

@override
void onClose() {
_mediaSubscription?.cancel();
_settingsSubscription?.cancel();
_backgroundSubscription?.cancel();
super.onClose();
}

Expand Down Expand Up @@ -91,6 +110,10 @@ class SettingsRepository extends DisposableInterface
Future<void> setSideBarWidth(double width) =>
_settingsLocal.setSideBarWidth(width);

@override
Future<void> setBackground(Uint8List? bytes) =>
bytes == null ? _backgroundLocal.delete() : _backgroundLocal.set(bytes);

/// Initializes [MediaSettingsHiveProvider.boxEvents] subscription.
Future<void> _initMediaSubscription() async {
_mediaSubscription = StreamIterator(_mediaLocal.boxEvents);
Expand Down Expand Up @@ -118,4 +141,18 @@ class SettingsRepository extends DisposableInterface
}
}
}

/// Initializes [BackgroundHiveProvider.boxEvents] subscription.
Future<void> _initBackgroundSubscription() async {
_backgroundSubscription = StreamIterator(_backgroundLocal.boxEvents);
while (await _backgroundSubscription!.moveNext()) {
BoxEvent event = _backgroundSubscription!.current;
if (event.deleted) {
background.value = null;
} else {
background.value = event.value.bytes;
background.refresh();
}
}
}
}
10 changes: 9 additions & 1 deletion lib/themes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ class Themes {
fontSize: 17,
fontWeight: FontWeight.w400,
),
sidebarColor: Colors.white.withOpacity(0.4),
),
],
colorScheme: colors,
scaffoldBackgroundColor: colors.background,
scaffoldBackgroundColor: Colors.transparent,
appBarTheme: ThemeData.light().appBarTheme.copyWith(
backgroundColor: colors.background,
foregroundColor: colors.primary,
Expand Down Expand Up @@ -238,17 +239,23 @@ class CustomBoxShadow extends BoxShadow {
class Style extends ThemeExtension<Style> {
const Style({
required this.boldBody,
required this.sidebarColor,
});

/// [TextStyle] to use in the body to make content readable.
final TextStyle boldBody;

/// [Color] of the [HomeView]'s side bar.
final Color sidebarColor;

@override
ThemeExtension<Style> copyWith({
TextStyle? boldBody,
Color? sidebarColor,
}) {
return Style(
boldBody: boldBody ?? this.boldBody,
sidebarColor: sidebarColor ?? this.sidebarColor,
);
}

Expand All @@ -260,6 +267,7 @@ class Style extends ThemeExtension<Style> {

return Style(
boldBody: TextStyle.lerp(boldBody, other.boldBody, t)!,
sidebarColor: Color.lerp(sidebarColor, other.sidebarColor, t)!,
);
}
}
4 changes: 4 additions & 0 deletions lib/ui/page/home/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// <https://www.gnu.org/licenses/agpl-3.0.html>.

import 'dart:async';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
Expand Down Expand Up @@ -78,6 +79,9 @@ class HomeController extends GetxController {
double get sideBarAllowedWidth =>
_settings.applicationSettings.value?.sideBarWidth ?? 350;

/// Returns the background's [Uint8List].
Rx<Uint8List?> get background => _settings.background;

@override
void onInit() {
super.onInit();
Expand Down
Loading