mirror of
https://github.com/zapstore/zapstore.git
synced 2026-10-05 20:48:24 +00:00
Settings model to persist logged in user
This commit is contained in:
@@ -9,12 +9,14 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
import 'package:zapstore/models/file_metadata.dart';
|
||||
import 'package:zapstore/models/release.dart';
|
||||
import 'package:zapstore/models/settings.dart';
|
||||
import 'package:zapstore/models/user.dart';
|
||||
|
||||
final adapterProvidersMap = <String, Provider<Adapter<DataModelMixin>>>{
|
||||
'apps': appsAdapterProvider,
|
||||
'fileMetadata': fileMetadataAdapterProvider,
|
||||
'releases': releasesAdapterProvider,
|
||||
'settings': settingsAdapterProvider,
|
||||
'users': usersAdapterProvider
|
||||
};
|
||||
|
||||
@@ -22,6 +24,7 @@ extension AdapterWidgetRefX on WidgetRef {
|
||||
Adapter<App> get apps => watch(appsAdapterProvider)..internalWatch = watch;
|
||||
Adapter<FileMetadata> get fileMetadata => watch(fileMetadataAdapterProvider)..internalWatch = watch;
|
||||
Adapter<Release> get releases => watch(releasesAdapterProvider)..internalWatch = watch;
|
||||
Adapter<Settings> get settings => watch(settingsAdapterProvider)..internalWatch = watch;
|
||||
Adapter<User> get users => watch(usersAdapterProvider)..internalWatch = watch;
|
||||
}
|
||||
|
||||
@@ -30,5 +33,6 @@ extension AdapterRefX on Ref {
|
||||
Adapter<App> get apps => watch(appsAdapterProvider)..internalWatch = watch as Watcher;
|
||||
Adapter<FileMetadata> get fileMetadata => watch(fileMetadataAdapterProvider)..internalWatch = watch as Watcher;
|
||||
Adapter<Release> get releases => watch(releasesAdapterProvider)..internalWatch = watch as Watcher;
|
||||
Adapter<Settings> get settings => watch(settingsAdapterProvider)..internalWatch = watch as Watcher;
|
||||
Adapter<User> get users => watch(usersAdapterProvider)..internalWatch = watch as Watcher;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:flutter_data/flutter_data.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:zapstore/models/user.dart';
|
||||
|
||||
part 'settings.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
@DataAdapter([SettingsAdapter])
|
||||
class Settings extends DataModel<Settings> {
|
||||
@override
|
||||
String get id => '_';
|
||||
final BelongsTo<User> user = BelongsTo();
|
||||
bool isLoggedIn = false;
|
||||
}
|
||||
|
||||
mixin SettingsAdapter on Adapter<Settings> {
|
||||
@override
|
||||
Future<void> onInitialized() async {
|
||||
// ensure it's always present
|
||||
if (!existsId('_')) {
|
||||
Settings().saveLocal();
|
||||
}
|
||||
super.onInitialized();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'settings.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// AdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// ignore_for_file: non_constant_identifier_names, duplicate_ignore
|
||||
|
||||
mixin _$SettingsAdapter on Adapter<Settings> {
|
||||
static final Map<String, RelationshipMeta> _kSettingsRelationshipMetas = {
|
||||
'user': RelationshipMeta<User>(
|
||||
name: 'user',
|
||||
type: 'users',
|
||||
kind: 'BelongsTo',
|
||||
instance: (_) => (_ as Settings).user,
|
||||
)
|
||||
};
|
||||
|
||||
@override
|
||||
Map<String, RelationshipMeta> get relationshipMetas =>
|
||||
_kSettingsRelationshipMetas;
|
||||
|
||||
@override
|
||||
Settings deserializeLocal(map, {String? key}) {
|
||||
map = transformDeserialize(map);
|
||||
return internalWrapStopInit(() => _$SettingsFromJson(map), key: key);
|
||||
}
|
||||
|
||||
@override
|
||||
Map<String, dynamic> serializeLocal(model, {bool withRelationships = true}) {
|
||||
final map = _$SettingsToJson(model);
|
||||
return transformSerialize(map, withRelationships: withRelationships);
|
||||
}
|
||||
}
|
||||
|
||||
final _settingsFinders = <String, dynamic>{};
|
||||
|
||||
class $SettingsAdapter = Adapter<Settings>
|
||||
with _$SettingsAdapter, SettingsAdapter;
|
||||
|
||||
final settingsAdapterProvider = Provider<Adapter<Settings>>(
|
||||
(ref) => $SettingsAdapter(ref, InternalHolder(_settingsFinders)));
|
||||
|
||||
extension SettingsAdapterX on Adapter<Settings> {
|
||||
SettingsAdapter get settingsAdapter => this as SettingsAdapter;
|
||||
}
|
||||
|
||||
extension SettingsRelationshipGraphNodeX on RelationshipGraphNode<Settings> {
|
||||
RelationshipGraphNode<User> get user {
|
||||
final meta = _$SettingsAdapter._kSettingsRelationshipMetas['user']
|
||||
as RelationshipMeta<User>;
|
||||
return meta.clone(
|
||||
parent: this is RelationshipMeta ? this as RelationshipMeta : null);
|
||||
}
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Settings _$SettingsFromJson(Map<String, dynamic> json) =>
|
||||
Settings()..isLoggedIn = json['isLoggedIn'] as bool;
|
||||
|
||||
Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
|
||||
'isLoggedIn': instance.isLoggedIn,
|
||||
};
|
||||
@@ -14,7 +14,6 @@ import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
import 'package:zapstore/models/release.dart';
|
||||
import 'package:zapstore/models/user.dart';
|
||||
import 'package:zapstore/services/session_service.dart';
|
||||
import 'package:zapstore/utils/extensions.dart';
|
||||
import 'package:zapstore/widgets/card.dart';
|
||||
import 'package:zapstore/widgets/pill_widget.dart';
|
||||
@@ -116,7 +115,7 @@ class AppDetailScreen extends HookConsumerWidget {
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(child: Text('Source')),
|
||||
SizedBox(child: Text('Source ')),
|
||||
Flexible(
|
||||
child: AutoSizeText(
|
||||
app.repository!,
|
||||
@@ -172,7 +171,7 @@ class AppDetailScreen extends HookConsumerWidget {
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('SHA-256 hash'),
|
||||
Text('SHA-256 hash '),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'${app.latestMetadata!.hash!.substring(0, 26)}...',
|
||||
@@ -454,8 +453,8 @@ class InstallButton extends ConsumerWidget {
|
||||
child: switch (app.status) {
|
||||
AppInstallStatus.noArch =>
|
||||
Text('Sorry, release does not support your device'),
|
||||
AppInstallStatus.downgrade =>
|
||||
Text('Installed version is higher, can\'t downgrade'),
|
||||
AppInstallStatus.downgrade => Text(
|
||||
'Installed version ${app.installedVersion ?? ''} is higher, can\'t downgrade'),
|
||||
AppInstallStatus.updated => Text('Open'),
|
||||
_ => switch (progress) {
|
||||
IdleInstallProgress() => app.canUpdate
|
||||
@@ -492,7 +491,7 @@ class InstallAlertDialog extends ConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final user = ref.watch(loggedInUser);
|
||||
final user = ref.settings.watchOne('_').model!.user.value;
|
||||
return AlertDialog(
|
||||
elevation: 10,
|
||||
title: Text(
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'package:purplebase/purplebase.dart';
|
||||
import 'package:zapstore/main.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/models/app.dart';
|
||||
import 'package:zapstore/services/session_service.dart';
|
||||
import 'package:zapstore/utils/extensions.dart';
|
||||
|
||||
class SettingsScreen extends HookConsumerWidget {
|
||||
@@ -16,6 +15,8 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final controller = useTextEditingController();
|
||||
final user = ref.settings.watchOne('_').model!.user.value;
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
@@ -44,7 +45,6 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
loadingWidget: SizedBox(
|
||||
width: 14, height: 14, child: CircularProgressIndicator()),
|
||||
onPressed: () async {
|
||||
final user = ref.read(loggedInUser);
|
||||
if (user == null) {
|
||||
scaffoldKey.currentState!.openDrawer();
|
||||
return;
|
||||
@@ -61,8 +61,7 @@ class SettingsScreen extends HookConsumerWidget {
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
ref.watch(loggedInUser) != null ? 'Send' : 'Tap to log in'),
|
||||
child: Text(user != null ? 'Send' : 'Tap to log in'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:zapstore/models/user.dart';
|
||||
|
||||
final loggedInUser = StateProvider<User?>((ref) => null);
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:gap/gap.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/services/session_service.dart';
|
||||
import 'package:zapstore/models/settings.dart';
|
||||
import 'package:zapstore/widgets/card.dart';
|
||||
|
||||
class AppDrawer extends HookConsumerWidget {
|
||||
@@ -12,7 +12,11 @@ class AppDrawer extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final user = ref.watch(loggedInUser);
|
||||
final user = ref.settings
|
||||
.watchOne('_', alsoWatch: (_) => {_.user})
|
||||
.model
|
||||
?.user
|
||||
.value;
|
||||
final controller = useTextEditingController();
|
||||
|
||||
return Padding(
|
||||
@@ -44,8 +48,8 @@ class AppDrawer extends HookConsumerWidget {
|
||||
color: Colors.lightBlue, size: 18),
|
||||
],
|
||||
),
|
||||
if (user.following.isNotEmpty)
|
||||
Text('${user.following.length} contacts'),
|
||||
// if (user.following.isNotEmpty)
|
||||
// Text('${user.following.length} contacts'),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -69,9 +73,9 @@ class AppDrawer extends HookConsumerWidget {
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
onPressed: () async {
|
||||
ref.read(loggedInUser.notifier).state = await ref.users
|
||||
.findOne(controller.text.trim(),
|
||||
params: {'contacts': true});
|
||||
final user =
|
||||
await ref.users.findOne(controller.text.trim());
|
||||
ref.settings.findOneLocalById('_')!.user.value = user;
|
||||
},
|
||||
builder: (context, child, callback, buttonState) {
|
||||
return ElevatedButton(
|
||||
@@ -84,7 +88,7 @@ class AppDrawer extends HookConsumerWidget {
|
||||
if (user != null)
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
ref.read(loggedInUser.notifier).state = null;
|
||||
ref.settings.findOneLocalById('_')!.user.value = null;
|
||||
controller.clear();
|
||||
},
|
||||
child: Text('Log out'),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:zapstore/services/session_service.dart';
|
||||
import 'package:zapstore/main.data.dart';
|
||||
import 'package:zapstore/widgets/card.dart';
|
||||
|
||||
class UserAvatar extends HookConsumerWidget {
|
||||
@@ -8,7 +8,7 @@ class UserAvatar extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final user = ref.watch(loggedInUser);
|
||||
final user = ref.settings.watchOne('_').model!.user.value;
|
||||
return CircularImage(url: user?.avatarUrl, size: 46);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user