mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2024-12-25 23:12:37 +01:00
Merge branch 'krille/stories-settings' into 'main'
feat: Settings for stories See merge request famedly/fluffychat!640
This commit is contained in:
commit
8789863906
@ -229,7 +229,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 1240;
|
LastSwiftUpdateCheck = 1240;
|
||||||
LastUpgradeCheck = 1020;
|
LastUpgradeCheck = 1300;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1300"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
@ -28,6 +28,7 @@ import 'package:fluffychat/pages/settings_ignore_list/settings_ignore_list.dart'
|
|||||||
import 'package:fluffychat/pages/settings_multiple_emotes/settings_multiple_emotes.dart';
|
import 'package:fluffychat/pages/settings_multiple_emotes/settings_multiple_emotes.dart';
|
||||||
import 'package:fluffychat/pages/settings_notifications/settings_notifications.dart';
|
import 'package:fluffychat/pages/settings_notifications/settings_notifications.dart';
|
||||||
import 'package:fluffychat/pages/settings_security/settings_security.dart';
|
import 'package:fluffychat/pages/settings_security/settings_security.dart';
|
||||||
|
import 'package:fluffychat/pages/settings_stories/settings_stories.dart';
|
||||||
import 'package:fluffychat/pages/settings_style/settings_style.dart';
|
import 'package:fluffychat/pages/settings_style/settings_style.dart';
|
||||||
import 'package:fluffychat/pages/sign_up/signup.dart';
|
import 'package:fluffychat/pages/sign_up/signup.dart';
|
||||||
import 'package:fluffychat/pages/story/story_page.dart';
|
import 'package:fluffychat/pages/story/story_page.dart';
|
||||||
@ -334,6 +335,11 @@ class AppRoutes {
|
|||||||
widget: const SettingsSecurity(),
|
widget: const SettingsSecurity(),
|
||||||
buildTransition: _dynamicTransition,
|
buildTransition: _dynamicTransition,
|
||||||
stackedRoutes: [
|
stackedRoutes: [
|
||||||
|
VWidget(
|
||||||
|
path: 'stories',
|
||||||
|
widget: const SettingsStories(),
|
||||||
|
buildTransition: _dynamicTransition,
|
||||||
|
),
|
||||||
VWidget(
|
VWidget(
|
||||||
path: 'ignorelist',
|
path: 'ignorelist',
|
||||||
widget: const SettingsIgnoreList(),
|
widget: const SettingsIgnoreList(),
|
||||||
|
@ -24,6 +24,11 @@ class SettingsSecurityView extends StatelessWidget {
|
|||||||
withScrolling: true,
|
withScrolling: true,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
|
ListTile(
|
||||||
|
trailing: const Icon(Icons.panorama_fish_eye),
|
||||||
|
title: Text(L10n.of(context).whoCanSeeMyStories),
|
||||||
|
onTap: () => VRouter.of(context).to('stories'),
|
||||||
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: const Icon(Icons.close),
|
trailing: const Icon(Icons.close),
|
||||||
title: Text(L10n.of(context).ignoredUsers),
|
title: Text(L10n.of(context).ignoredUsers),
|
||||||
@ -61,35 +66,23 @@ class SettingsSecurityView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
trailing: const Icon(Icons.vpn_key_outlined),
|
trailing: const Icon(Icons.vpn_key_outlined),
|
||||||
),
|
),
|
||||||
|
if (!Matrix.of(context).client.encryption.crossSigning.enabled)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(L10n.of(context).crossSigningEnabled),
|
title: Text(L10n.of(context).crossSigningEnabled),
|
||||||
trailing:
|
trailing: const Icon(Icons.error, color: Colors.red),
|
||||||
Matrix.of(context).client.encryption.crossSigning.enabled
|
onTap: () => controller.showBootstrapDialog(context),
|
||||||
? const Icon(Icons.check, color: Colors.green)
|
|
||||||
: const Icon(Icons.error, color: Colors.red),
|
|
||||||
onTap:
|
|
||||||
Matrix.of(context).client.encryption.crossSigning.enabled
|
|
||||||
? null
|
|
||||||
: () => controller.showBootstrapDialog(context),
|
|
||||||
),
|
),
|
||||||
|
if (!Matrix.of(context).client.encryption.keyManager.enabled)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(L10n.of(context).onlineKeyBackupEnabled),
|
title: Text(L10n.of(context).onlineKeyBackupEnabled),
|
||||||
trailing:
|
trailing: const Icon(Icons.error, color: Colors.red),
|
||||||
Matrix.of(context).client.encryption.keyManager.enabled
|
onTap: () => controller.showBootstrapDialog(context),
|
||||||
? const Icon(Icons.check, color: Colors.green)
|
|
||||||
: const Icon(Icons.error, color: Colors.red),
|
|
||||||
onTap: Matrix.of(context).client.encryption.keyManager.enabled
|
|
||||||
? null
|
|
||||||
: () => controller.showBootstrapDialog(context),
|
|
||||||
),
|
),
|
||||||
|
if (Matrix.of(context).client.isUnknownSession)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('Session verified'),
|
title: const Text('Session verified'),
|
||||||
trailing: !Matrix.of(context).client.isUnknownSession
|
trailing: const Icon(Icons.error, color: Colors.red),
|
||||||
? const Icon(Icons.check, color: Colors.green)
|
onTap: () => controller.showBootstrapDialog(context),
|
||||||
: const Icon(Icons.error, color: Colors.red),
|
|
||||||
onTap: !Matrix.of(context).client.isUnknownSession
|
|
||||||
? null
|
|
||||||
: () => controller.showBootstrapDialog(context),
|
|
||||||
),
|
),
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: () async {
|
future: () async {
|
||||||
@ -104,14 +97,12 @@ class SettingsSecurityView extends StatelessWidget {
|
|||||||
.crossSigning
|
.crossSigning
|
||||||
.isCached());
|
.isCached());
|
||||||
}(),
|
}(),
|
||||||
builder: (context, snapshot) => ListTile(
|
builder: (context, snapshot) => snapshot.data == true
|
||||||
|
? Container()
|
||||||
|
: ListTile(
|
||||||
title: Text(L10n.of(context).keysCached),
|
title: Text(L10n.of(context).keysCached),
|
||||||
trailing: snapshot.data == true
|
trailing: const Icon(Icons.error, color: Colors.red),
|
||||||
? const Icon(Icons.check, color: Colors.green)
|
onTap: () => controller.showBootstrapDialog(context),
|
||||||
: const Icon(Icons.error, color: Colors.red),
|
|
||||||
onTap: snapshot.data == true
|
|
||||||
? null
|
|
||||||
: () => controller.showBootstrapDialog(context),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
97
lib/pages/settings_stories/settings_stories.dart
Normal file
97
lib/pages/settings_stories/settings_stories.dart
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//@dart=2.12
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||||
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/pages/settings_stories/settings_stories_view.dart';
|
||||||
|
import 'package:fluffychat/widgets/matrix.dart';
|
||||||
|
import '../../utils/matrix_sdk_extensions.dart/client_stories_extension.dart';
|
||||||
|
|
||||||
|
class SettingsStories extends StatefulWidget {
|
||||||
|
const SettingsStories({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
SettingsStoriesController createState() => SettingsStoriesController();
|
||||||
|
}
|
||||||
|
|
||||||
|
class SettingsStoriesController extends State<SettingsStories> {
|
||||||
|
final Map<User, bool> users = {};
|
||||||
|
|
||||||
|
Room? _storiesRoom;
|
||||||
|
|
||||||
|
Future<void>? loadUsers;
|
||||||
|
|
||||||
|
bool noStoriesRoom = false;
|
||||||
|
|
||||||
|
Future<void> toggleUser(User user) async {
|
||||||
|
final room = _storiesRoom;
|
||||||
|
if (room == null) return;
|
||||||
|
|
||||||
|
if (users[user] ?? false) {
|
||||||
|
// Kick user from stories room and add to block list
|
||||||
|
final blockList = room.client.storiesBlockList;
|
||||||
|
blockList.add(user.id);
|
||||||
|
await showFutureLoadingDialog(
|
||||||
|
context: context,
|
||||||
|
future: () async {
|
||||||
|
await user.kick();
|
||||||
|
await room.client.setStoriesBlockList(blockList.toSet().toList());
|
||||||
|
setState(() {
|
||||||
|
users[user] = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invite user to stories room and remove from block list
|
||||||
|
final blockList = room.client.storiesBlockList;
|
||||||
|
blockList.remove(user.id);
|
||||||
|
await showFutureLoadingDialog(
|
||||||
|
context: context,
|
||||||
|
future: () async {
|
||||||
|
await room.client.setStoriesBlockList(blockList);
|
||||||
|
await room.invite(user.id);
|
||||||
|
setState(() {
|
||||||
|
users[user] = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _loadUsers() async {
|
||||||
|
final room =
|
||||||
|
_storiesRoom = await Matrix.of(context).client.getStoriesRoom(context);
|
||||||
|
if (room == null) {
|
||||||
|
noStoriesRoom = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final users = await room.requestParticipants();
|
||||||
|
users.removeWhere((u) => u.id == room.client.userID);
|
||||||
|
final contacts = Matrix.of(context)
|
||||||
|
.client
|
||||||
|
.contacts
|
||||||
|
.where((contact) => !users.any((u) => u.id == contact.id));
|
||||||
|
for (final user in contacts) {
|
||||||
|
this.users[user] = false;
|
||||||
|
}
|
||||||
|
for (final user in users) {
|
||||||
|
this.users[user] = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
WidgetsBinding.instance?.addPostFrameCallback((_) {
|
||||||
|
setState(() {
|
||||||
|
loadUsers = _loadUsers();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => SettingsStoriesView(this);
|
||||||
|
}
|
49
lib/pages/settings_stories/settings_stories_view.dart
Normal file
49
lib/pages/settings_stories/settings_stories_view.dart
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//@dart=2.12
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:fluffychat/pages/settings_stories/settings_stories.dart';
|
||||||
|
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||||
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
|
|
||||||
|
class SettingsStoriesView extends StatelessWidget {
|
||||||
|
final SettingsStoriesController controller;
|
||||||
|
const SettingsStoriesView(this.controller, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(),
|
||||||
|
body: FutureBuilder(
|
||||||
|
future: controller.loadUsers,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final error = snapshot.error;
|
||||||
|
if (error != null) {
|
||||||
|
return Center(child: Text(error.toLocalizedString(context)));
|
||||||
|
}
|
||||||
|
if (snapshot.connectionState != ConnectionState.done) {
|
||||||
|
return const Center(
|
||||||
|
child: CircularProgressIndicator.adaptive(
|
||||||
|
strokeWidth: 2,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: controller.users.length,
|
||||||
|
itemBuilder: (context, i) {
|
||||||
|
final user = controller.users.keys.toList()[i];
|
||||||
|
return SwitchListTile.adaptive(
|
||||||
|
value: controller.users[user] ?? false,
|
||||||
|
onChanged: (_) => controller.toggleUser(user),
|
||||||
|
secondary: Avatar(
|
||||||
|
mxContent: user.avatarUrl,
|
||||||
|
name: user.calcDisplayname(),
|
||||||
|
),
|
||||||
|
title: Text(user.calcDisplayname()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user