usability test updates - don't stack space details, always suggest new chats in spaces
parent
d29d5ce379
commit
f15d79179d
@ -1,96 +0,0 @@
|
|||||||
import 'dart:async';
|
|
||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:matrix/matrix.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
|
||||||
import 'package:fluffychat/widgets/layouts/empty_page.dart';
|
|
||||||
import '../../../widgets/matrix.dart';
|
|
||||||
import '../../utils/error_handler.dart';
|
|
||||||
import '../../utils/set_class_name.dart';
|
|
||||||
import '../../widgets/space/class_settings.dart';
|
|
||||||
import 'class_settings_view.dart';
|
|
||||||
import 'p_class_widgets/room_rules_editor.dart';
|
|
||||||
|
|
||||||
class ClassSettingsPage extends StatefulWidget {
|
|
||||||
const ClassSettingsPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<ClassSettingsPage> createState() => ClassSettingsController();
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClassSettingsController extends State<ClassSettingsPage> {
|
|
||||||
PangeaController pangeaController = MatrixState.pangeaController;
|
|
||||||
|
|
||||||
final GlobalKey<RoomRulesState> rulesEditorKey = GlobalKey<RoomRulesState>();
|
|
||||||
final GlobalKey<ClassSettingsState> classSettingsKey =
|
|
||||||
GlobalKey<ClassSettingsState>();
|
|
||||||
|
|
||||||
Room? room;
|
|
||||||
|
|
||||||
String? get roomId => GoRouterState.of(context).pathParameters['roomid'];
|
|
||||||
|
|
||||||
Future<void> handleSave(BuildContext context) async {
|
|
||||||
if (classSettingsKey.currentState!.sameLanguages) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(L10n.of(context)!.noIdenticalLanguages),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (rulesEditorKey.currentState != null) {
|
|
||||||
await rulesEditorKey.currentState?.setRoomRules(roomId!);
|
|
||||||
} else {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
ErrorHandler.logError(m: "Null rules editor state");
|
|
||||||
}
|
|
||||||
if (classSettingsKey.currentState != null) {
|
|
||||||
await classSettingsKey.currentState?.setClassSettings(
|
|
||||||
roomId!,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
ErrorHandler.logError(m: "Null class settings state");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void goback(BuildContext context) {
|
|
||||||
context.push("/spaces/$roomId");
|
|
||||||
}
|
|
||||||
|
|
||||||
String get className =>
|
|
||||||
Matrix.of(context).client.getRoomById(roomId!)?.name ?? '';
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
// TODO: implement initState
|
|
||||||
super.initState();
|
|
||||||
|
|
||||||
Future.delayed(Duration.zero, () {
|
|
||||||
room = Matrix.of(context).client.getRoomById(roomId!);
|
|
||||||
if (room == null) {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
context.pop();
|
|
||||||
}
|
|
||||||
setState(() {});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//PTODO - show loading widget
|
|
||||||
|
|
||||||
void setDisplaynameAction() => setClassDisplayname(context, roomId);
|
|
||||||
|
|
||||||
bool showEditNameIcon = false;
|
|
||||||
void hoverEditNameIcon(bool hovering) =>
|
|
||||||
setState(() => showEditNameIcon = !showEditNameIcon);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => room != null
|
|
||||||
? ClassSettingsPageView(controller: this)
|
|
||||||
: const EmptyPage();
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/pangea/pages/class_settings/class_settings_page.dart';
|
|
||||||
import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart';
|
|
||||||
import 'package:fluffychat/pangea/widgets/space/class_settings.dart';
|
|
||||||
import '../../../widgets/layouts/max_width_body.dart';
|
|
||||||
|
|
||||||
class ClassSettingsPageView extends StatelessWidget {
|
|
||||||
final ClassSettingsController controller;
|
|
||||||
const ClassSettingsPageView({super.key, required this.controller});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
debugPrint("in class settings page with roomId ${controller.roomId}");
|
|
||||||
// PTODO-Lala - make the page scrollable anywhere, not just in the area of the elements
|
|
||||||
// so like, the user should be able scroll using the mouse wheel from anywhere within this view
|
|
||||||
// currently, your cursor needs be horizontally within the tiles in order to scroll
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
leading: GoRouterState.of(context).path?.startsWith('/spaces/') ?? false
|
|
||||||
? null
|
|
||||||
: IconButton(
|
|
||||||
icon: const Icon(Icons.close_outlined),
|
|
||||||
onPressed: () => controller.goback(context),
|
|
||||||
),
|
|
||||||
centerTitle: true,
|
|
||||||
title: Text(L10n.of(context)!.classSettings),
|
|
||||||
),
|
|
||||||
body: ListView(
|
|
||||||
children: [
|
|
||||||
MaxWidthBody(
|
|
||||||
child: ListTile(
|
|
||||||
title: Center(
|
|
||||||
child: TextButton.icon(
|
|
||||||
onPressed: controller.setDisplaynameAction,
|
|
||||||
onHover: controller.hoverEditNameIcon,
|
|
||||||
style: TextButton.styleFrom(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 25),
|
|
||||||
),
|
|
||||||
label: Visibility(
|
|
||||||
visible: controller.showEditNameIcon,
|
|
||||||
child: Icon(
|
|
||||||
Icons.edit,
|
|
||||||
color: Theme.of(context).colorScheme.onBackground,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
icon: Text(
|
|
||||||
controller.className,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MaxWidthBody(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
ClassSettings(
|
|
||||||
roomId: controller.roomId,
|
|
||||||
startOpen: true,
|
|
||||||
),
|
|
||||||
RoomRulesEditor(roomId: controller.roomId),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton.extended(
|
|
||||||
onPressed: () => showFutureLoadingDialog(
|
|
||||||
context: context,
|
|
||||||
future: () => controller.handleSave(context),
|
|
||||||
),
|
|
||||||
label: Text(L10n.of(context)!.saveChanges),
|
|
||||||
icon: const Icon(Icons.save_outlined),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
|
|
||||||
class ClassSettingsButton extends StatelessWidget {
|
|
||||||
const ClassSettingsButton({super.key});
|
|
||||||
|
|
||||||
// final PangeaController _pangeaController = MatrixState.pangeaController;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
// final roomId = GoRouterState.of(context).pathParameters['roomid'];
|
|
||||||
|
|
||||||
final iconColor = Theme.of(context).textTheme.bodyLarge!.color;
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
ListTile(
|
|
||||||
// enabled: roomId != null &&
|
|
||||||
// _pangeaController.classController
|
|
||||||
// .getClassModelBySpaceIdLocal(roomId) !=
|
|
||||||
// null,
|
|
||||||
title: Text(
|
|
||||||
L10n.of(context)!.classSettings,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: Text(L10n.of(context)!.classSettingsDesc),
|
|
||||||
leading: CircleAvatar(
|
|
||||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
|
||||||
foregroundColor: iconColor,
|
|
||||||
child: const Icon(Icons.settings_outlined),
|
|
||||||
),
|
|
||||||
onTap: () => context.go('/class_settings'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,122 +0,0 @@
|
|||||||
import 'dart:developer';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
||||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:matrix/matrix.dart' as sdk;
|
|
||||||
import 'package:matrix/matrix.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/pangea/pages/new_class/new_class_view.dart';
|
|
||||||
import 'package:fluffychat/pangea/utils/class_code.dart';
|
|
||||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
|
||||||
import 'package:fluffychat/widgets/matrix.dart';
|
|
||||||
import '../../controllers/pangea_controller.dart';
|
|
||||||
import '../../widgets/space/class_settings.dart';
|
|
||||||
import '../class_settings/p_class_widgets/room_rules_editor.dart';
|
|
||||||
|
|
||||||
class NewClass extends StatefulWidget {
|
|
||||||
const NewClass({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
NewClassController createState() => NewClassController();
|
|
||||||
}
|
|
||||||
|
|
||||||
class NewClassController extends State<NewClass> {
|
|
||||||
TextEditingController controller = TextEditingController();
|
|
||||||
|
|
||||||
final PangeaController pangeaController = MatrixState.pangeaController;
|
|
||||||
final GlobalKey<RoomRulesState> rulesEditorKey = GlobalKey<RoomRulesState>();
|
|
||||||
final GlobalKey<ClassSettingsState> classSettingsKey =
|
|
||||||
GlobalKey<ClassSettingsState>();
|
|
||||||
|
|
||||||
void submitAction([_]) async {
|
|
||||||
//TODO: validate that object is complete
|
|
||||||
final matrix = Matrix.of(context);
|
|
||||||
if (controller.text.isEmpty) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(L10n.of(context)!.classNameRequired),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (classSettingsKey.currentState == null) {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
}
|
|
||||||
if (classSettingsKey.currentState!.sameLanguages) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
SnackBar(
|
|
||||||
content: Text(L10n.of(context)!.noIdenticalLanguages),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final roomID = await showFutureLoadingDialog(
|
|
||||||
context: context,
|
|
||||||
future: () async {
|
|
||||||
final String roomID = await matrix.client.createRoom(
|
|
||||||
//PTODO - investigate effects of changing visibility from public
|
|
||||||
preset: sdk.CreateRoomPreset.publicChat,
|
|
||||||
creationContent: {
|
|
||||||
'type': RoomCreationTypes.mSpace,
|
|
||||||
},
|
|
||||||
visibility: sdk.Visibility.public,
|
|
||||||
// roomAliasName: controller.text.isNotEmpty
|
|
||||||
// ? "${matrix.client.userID!.localpart}-${controller.text.trim().toLowerCase().replaceAll(' ', '_')}"
|
|
||||||
// : null,
|
|
||||||
roomAliasName: ClassCodeUtil.generateClassCode(),
|
|
||||||
name: controller.text.isNotEmpty ? controller.text : null,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (rulesEditorKey.currentState != null) {
|
|
||||||
await rulesEditorKey.currentState!.setRoomRules(roomID);
|
|
||||||
} else {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
ErrorHandler.logError(m: "Null rules editor state");
|
|
||||||
}
|
|
||||||
if (classSettingsKey.currentState != null) {
|
|
||||||
await classSettingsKey.currentState!.setClassSettings(
|
|
||||||
roomID,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
ErrorHandler.logError(m: "Null class settings state");
|
|
||||||
}
|
|
||||||
return roomID;
|
|
||||||
},
|
|
||||||
onError: (e) {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
return e;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (roomID.error == null && roomID.result is String) {
|
|
||||||
pangeaController.classController.setActiveSpaceIdInChatListController(
|
|
||||||
roomID.result!,
|
|
||||||
);
|
|
||||||
context.push('/spaces/${roomID.result!}');
|
|
||||||
} else {
|
|
||||||
debugger(when: kDebugMode);
|
|
||||||
ErrorHandler.logError(e: roomID.error, s: StackTrace.current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
// TODO: implement initState
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => NewSpaceView(this);
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
|
||||||
|
|
||||||
import 'package:fluffychat/pangea/constants/class_default_values.dart';
|
|
||||||
import 'package:fluffychat/pangea/pages/new_class/new_class.dart';
|
|
||||||
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
|
||||||
import '../../widgets/space/class_settings.dart';
|
|
||||||
import '../class_settings/p_class_widgets/room_rules_editor.dart';
|
|
||||||
|
|
||||||
class NewSpaceView extends StatelessWidget {
|
|
||||||
// #Pangea
|
|
||||||
// final NewSpaceController controller;
|
|
||||||
final NewClassController controller;
|
|
||||||
// Pangea#
|
|
||||||
|
|
||||||
const NewSpaceView(this.controller, {super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
// #Pangea
|
|
||||||
centerTitle: true,
|
|
||||||
// Pangea#
|
|
||||||
title: Text(L10n.of(context)!.createNewClass),
|
|
||||||
),
|
|
||||||
body: MaxWidthBody(
|
|
||||||
// #Pangea
|
|
||||||
child: ListView(
|
|
||||||
// child: Column(
|
|
||||||
// mainAxisSize: MainAxisSize.min,
|
|
||||||
// #Pangea
|
|
||||||
children: <Widget>[
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(12.0),
|
|
||||||
child: TextField(
|
|
||||||
// #Pangea
|
|
||||||
maxLength: ClassDefaultValues.maxClassName,
|
|
||||||
maxLengthEnforcement: MaxLengthEnforcement.enforced,
|
|
||||||
// #Pangea
|
|
||||||
controller: controller.controller,
|
|
||||||
autofocus: true,
|
|
||||||
autocorrect: false,
|
|
||||||
textInputAction: TextInputAction.go,
|
|
||||||
onSubmitted: controller.submitAction,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: L10n.of(context)!.spaceName,
|
|
||||||
prefixIcon: const Icon(Icons.people_outlined),
|
|
||||||
hintText: L10n.of(context)!.enterASpacepName,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
// #Pangea
|
|
||||||
ClassSettings(
|
|
||||||
key: controller.classSettingsKey,
|
|
||||||
roomId: null,
|
|
||||||
startOpen: true,
|
|
||||||
),
|
|
||||||
RoomRulesEditor(
|
|
||||||
key: controller.rulesEditorKey,
|
|
||||||
roomId: null,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 45),
|
|
||||||
// SwitchListTile.adaptive(
|
|
||||||
// title: Text(L10n.of(context)!.spaceIsPublic),
|
|
||||||
// value: controller.publicGroup,
|
|
||||||
// onChanged: controller.setPublicGroup,
|
|
||||||
// ),
|
|
||||||
// ListTile(
|
|
||||||
// trailing: const Padding(
|
|
||||||
// padding: EdgeInsets.symmetric(horizontal: 16.0),
|
|
||||||
// child: Icon(Icons.info_outlined),
|
|
||||||
// ),
|
|
||||||
// subtitle: Text(L10n.of(context)!.newSpaceDescription),
|
|
||||||
// ),
|
|
||||||
// #Pangea
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
floatingActionButton: FloatingActionButton(
|
|
||||||
onPressed: controller.submitAction,
|
|
||||||
child: const Icon(Icons.arrow_forward_outlined),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue