Merge pull request #267 from pangeachat/suggested-toggle

toggle to set suggested status for all spaces
pull/1183/head
ggurdin 1 year ago committed by GitHub
commit 6a3d04707e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -3681,24 +3681,8 @@
"lockSpace": "Lock Space", "lockSpace": "Lock Space",
"lockChat": "Lock Chat", "lockChat": "Lock Chat",
"archiveSpace": "Archive Space", "archiveSpace": "Archive Space",
"suggestTo": "Suggest to {spaceName}", "suggestToChat": "Suggest this chat",
"@suggestTo": { "suggestToChatDesc": "Suggested chats will appear in chat lists",
"placeholders": {
"spaceName": {}
}
},
"suggestChatDesc": "Suggested chats will appear in the chat list for {spaceName}",
"@suggestToDesc": {
"placeholders": {
"spaceName": {}
}
},
"suggestExchangeDesc": "Suggested exchanges will appear in the chat list for {spaceName}",
"@suggestToExchangeDesc": {
"placeholders": {
"spaceName": {}
}
},
"acceptSelection": "Accept Correction", "acceptSelection": "Accept Correction",
"acceptSelectionAnyway": "Use this anyway", "acceptSelectionAnyway": "Use this anyway",
"makingActivity": "Making activity", "makingActivity": "Making activity",

@ -130,9 +130,7 @@ class NewGroupController extends State<NewGroup> {
powerLevelContentOverride: powerLevelContentOverride:
await ClassChatPowerLevels.powerLevelOverrideForClassChat( await ClassChatPowerLevels.powerLevelOverrideForClassChat(
context, context,
addToSpaceKey.currentState!.parents addToSpaceKey.currentState!.parents,
.map((suggestionStatus) => suggestionStatus.room)
.toList(),
), ),
invite: [ invite: [
if (addConversationBotKey.currentState?.addBot ?? false) if (addConversationBotKey.currentState?.addBot ?? false)

@ -176,9 +176,7 @@ class NewSpaceController extends State<NewSpace> {
powerLevelContentOverride: addToSpaceKey.currentState != null powerLevelContentOverride: addToSpaceKey.currentState != null
? await ClassChatPowerLevels.powerLevelOverrideForClassChat( ? await ClassChatPowerLevels.powerLevelOverrideForClassChat(
context, context,
addToSpaceKey.currentState!.parents addToSpaceKey.currentState!.parents,
.map((suggestionStatus) => suggestionStatus.room)
.toList(),
) )
: null, : null,
// initialState: [ // initialState: [

@ -34,8 +34,9 @@ class ClassController extends BaseController {
Future<void> fixClassPowerLevels() async { Future<void> fixClassPowerLevels() async {
try { try {
final List<Future<void>> classFixes = []; final List<Future<void>> classFixes = [];
for (final room in (await _pangeaController final teacherSpaces = await _pangeaController
.matrixState.client.classesAndExchangesImTeaching)) { .matrixState.client.classesAndExchangesImTeaching;
for (final room in teacherSpaces) {
classFixes.add(room.setClassPowerLevels()); classFixes.add(room.setClassPowerLevels());
} }
await Future.wait(classFixes); await Future.wait(classFixes);

@ -62,13 +62,19 @@ extension ClassAndExchangeSettingsRoomExtension on Room {
} }
final Event? currentPower = getState(EventTypes.RoomPowerLevels); final Event? currentPower = getState(EventTypes.RoomPowerLevels);
final Map<String, dynamic>? currentPowerContent = final Map<String, dynamic>? currentPowerContent =
currentPower?.content["events"] as Map<String, dynamic>?; currentPower?.content as Map<String, dynamic>?;
final spaceChildPower = currentPowerContent?[EventTypes.spaceChild]; if (currentPowerContent == null) {
return;
}
if (!(currentPowerContent.containsKey("events"))) {
currentPowerContent["events"] = {};
}
final spaceChildPower =
currentPowerContent["events"][EventTypes.spaceChild];
final studentAnalyticsPower = final studentAnalyticsPower =
currentPowerContent?[PangeaEventTypes.studentAnalyticsSummary]; currentPowerContent[PangeaEventTypes.studentAnalyticsSummary];
if ((spaceChildPower == null || studentAnalyticsPower == null) && if ((spaceChildPower == null || studentAnalyticsPower == null)) {
currentPowerContent != null) {
currentPowerContent["events"][EventTypes.spaceChild] = 0; currentPowerContent["events"][EventTypes.spaceChild] = 0;
currentPowerContent["events"] currentPowerContent["events"]
[PangeaEventTypes.studentAnalyticsSummary] = 0; [PangeaEventTypes.studentAnalyticsSummary] = 0;

@ -253,11 +253,10 @@ extension PangeaRoom on Room {
BotOptionsModel? get botOptions => _botOptions; BotOptionsModel? get botOptions => _botOptions;
Future<bool> suggestedInSpace(Room space) async => Future<void> setSuggested(bool suggested) async =>
await _suggestedInSpace(space); await _setSuggested(suggested);
Future<void> setSuggestedInSpace(bool suggest, Room space) async => Future<bool> isSuggested() async => await _isSuggested();
await _setSuggestedInSpace(suggest, space);
// user_permissions // user_permissions

@ -55,7 +55,40 @@ extension RoomSettingsRoomExtension on Room {
); );
} }
Future<bool> _suggestedInSpace(Room space) async { Future<bool> _isSuggested() async {
final List<Room> spaceParents = client.rooms
.where(
(room) =>
room.isSpace &&
room.spaceChildren.any(
(sc) => sc.roomId == id,
),
)
.toList();
for (final parent in spaceParents) {
final suggested = await _isSuggestedInSpace(parent);
if (!suggested) return false;
}
return true;
}
Future<void> _setSuggested(bool suggested) async {
final List<Room> spaceParents = client.rooms
.where(
(room) =>
room.isSpace &&
room.spaceChildren.any(
(sc) => sc.roomId == id,
),
)
.toList();
for (final parent in spaceParents) {
await _setSuggestedInSpace(suggested, parent);
}
}
Future<bool> _isSuggestedInSpace(Room space) async {
try { try {
final Map<String, dynamic> resp = final Map<String, dynamic> resp =
await client.getRoomStateWithKey(space.id, EventTypes.spaceChild, id); await client.getRoomStateWithKey(space.id, EventTypes.spaceChild, id);

@ -33,9 +33,10 @@ class AddToSpaceToggles extends StatefulWidget {
class AddToSpaceState extends State<AddToSpaceToggles> { class AddToSpaceState extends State<AddToSpaceToggles> {
late Room? room; late Room? room;
late List<SuggestionStatus> parents; late List<Room> parents;
late List<Room> possibleParents; late List<Room> possibleParents;
late bool isOpen; late bool isOpen;
late bool isSuggested;
AddToSpaceState({Key? key}); AddToSpaceState({Key? key});
@ -46,6 +47,9 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
? Matrix.of(context).client.getRoomById(widget.roomId!) ? Matrix.of(context).client.getRoomById(widget.roomId!)
: null; : null;
isSuggested = true;
room?.isSuggested().then((value) => isSuggested = value);
possibleParents = Matrix.of(context) possibleParents = Matrix.of(context)
.client .client
.rooms .rooms
@ -63,8 +67,6 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
(r) => (r) =>
r.spaceChildren.any((room) => room.roomId == widget.roomId), r.spaceChildren.any((room) => room.roomId == widget.roomId),
) )
.map((r) => SuggestionStatus(false, r))
.cast<SuggestionStatus>()
.toList() .toList()
: []; : [];
@ -72,7 +74,7 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
final activeSpace = final activeSpace =
Matrix.of(context).client.getRoomById(widget.activeSpaceId!); Matrix.of(context).client.getRoomById(widget.activeSpaceId!);
if (activeSpace != null && activeSpace.canIAddSpaceChild(null)) { if (activeSpace != null && activeSpace.canIAddSpaceChild(null)) {
parents.add(SuggestionStatus(true, activeSpace)); parents.add(activeSpace);
} else { } else {
ErrorHandler.logError( ErrorHandler.logError(
e: Exception('activeSpaceId ${widget.activeSpaceId} not found'), e: Exception('activeSpaceId ${widget.activeSpaceId} not found'),
@ -84,10 +86,9 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
//if possibleParent in parents, put first //if possibleParent in parents, put first
//use sort but use any instead of contains because contains uses == and we want to compare by id //use sort but use any instead of contains because contains uses == and we want to compare by id
possibleParents.sort((a, b) { possibleParents.sort((a, b) {
if (parents.any((suggestionStatus) => suggestionStatus.room.id == a.id)) { if (parents.any((parent) => parent.id == a.id)) {
return -1; return -1;
} else if (parents } else if (parents.any((parent) => parent.id == b.id)) {
.any((suggestionStatus) => suggestionStatus.room.id == b.id)) {
return 1; return 1;
} else { } else {
return a.name.compareTo(b.name); return a.name.compareTo(b.name);
@ -95,35 +96,21 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
}); });
isOpen = widget.startOpen; isOpen = widget.startOpen;
initSuggestedParents();
super.initState(); super.initState();
} }
Future<void> initSuggestedParents() async {
if (room != null) {
for (var i = 0; i < parents.length; i++) {
final parent = parents[i];
final bool suggested =
await room?.suggestedInSpace(parent.room) ?? false;
parents[i].suggested = suggested;
}
setState(() {});
}
}
Future<void> _addSingleSpace(String roomToAddId, Room newParent) async { Future<void> _addSingleSpace(String roomToAddId, Room newParent) async {
GoogleAnalytics.addParent(roomToAddId, newParent.classCode); GoogleAnalytics.addParent(roomToAddId, newParent.classCode);
await newParent.setSpaceChild( await newParent.setSpaceChild(
roomToAddId, roomToAddId,
suggested: isSuggestedInSpace(newParent), suggested: isSuggested,
); );
await setSuggested(true, newParent);
} }
Future<void> addSpaces(String roomToAddId) async { Future<void> addSpaces(String roomToAddId) async {
final List<Future<void>> addFutures = []; final List<Future<void>> addFutures = [];
for (final SuggestionStatus newParent in parents) { for (final Room parent in parents) {
addFutures.add(_addSingleSpace(roomToAddId, newParent.room)); addFutures.add(_addSingleSpace(roomToAddId, parent));
} }
await addFutures.wait; await addFutures.wait;
} }
@ -148,39 +135,18 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
setState( setState(
() => add () => add
? parents.add(SuggestionStatus(true, possibleParent)) ? parents.add(possibleParent)
: parents.removeWhere( : parents.removeWhere(
(suggestionStatus) => (parent) => parent.id == possibleParent.id,
suggestionStatus.room.id == possibleParent.id,
), ),
); );
} }
Future<void> setSuggested(bool suggest, Room possibleParent) async {
if (room != null) {
await showFutureLoadingDialog(
context: context,
future: () => room!.setSuggestedInSpace(suggest, possibleParent),
);
}
for (final SuggestionStatus suggestionStatus in parents) {
if (suggestionStatus.room.id == possibleParent.id) {
suggestionStatus.suggested = suggest;
}
}
setState(() {});
}
bool isSuggestedInSpace(Room parent) =>
parents.firstWhereOrNull((r) => r.room.id == parent.id)?.suggested ??
false;
Widget getAddToSpaceToggleItem(int index) { Widget getAddToSpaceToggleItem(int index) {
final Room possibleParent = possibleParents[index]; final Room possibleParent = possibleParents[index];
final String possibleParentName = possibleParent.getLocalizedDisplayname(); final bool canAdd = !(!possibleParent.isRoomAdmin &&
final bool canAdd = possibleParent.canIAddSpaceChild(room); widget.mode == AddToClassMode.exchange) &&
possibleParent.canIAddSpaceChild(room);
return Opacity( return Opacity(
opacity: canAdd ? 1 : 0.5, opacity: canAdd ? 1 : 0.5,
@ -189,7 +155,7 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
SwitchListTile.adaptive( SwitchListTile.adaptive(
title: possibleParent.nameAndRoomTypeIcon(), title: possibleParent.nameAndRoomTypeIcon(),
activeColor: AppConfig.activeToggleColor, activeColor: AppConfig.activeToggleColor,
value: parents.any((r) => r.room.id == possibleParent.id), value: parents.any((r) => r.id == possibleParent.id),
onChanged: (bool add) => canAdd onChanged: (bool add) => canAdd
? handleAdd(add, possibleParent) ? handleAdd(add, possibleParent)
: ScaffoldMessenger.of(context).showSnackBar( : ScaffoldMessenger.of(context).showSnackBar(
@ -198,53 +164,6 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
), ),
), ),
), ),
AnimatedSize(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
child: parents.any((r) => r.room.id == possibleParent.id)
? SwitchListTile.adaptive(
title: Row(
children: [
const SizedBox(width: 32),
Expanded(
child: Text(
L10n.of(context)!.suggestTo(possibleParentName),
style: TextStyle(
color: Theme.of(context).colorScheme.secondary,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
subtitle: Row(
children: [
const SizedBox(width: 32),
Expanded(
child: Text(
widget.mode == AddToClassMode.chat
? L10n.of(context)!
.suggestChatDesc(possibleParentName)
: L10n.of(context)!.suggestExchangeDesc(
possibleParentName,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
activeColor: AppConfig.activeToggleColor,
value: isSuggestedInSpace(possibleParent),
onChanged: (bool suggest) => canAdd
? setSuggested(suggest, possibleParent)
: ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(L10n.of(context)!.noPermission),
),
),
)
: Container(),
),
Divider( Divider(
height: 0.5, height: 0.5,
color: Theme.of(context).colorScheme.secondary.withAlpha(25), color: Theme.of(context).colorScheme.secondary.withAlpha(25),
@ -254,6 +173,16 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
); );
} }
Future<void> setSuggested(bool suggested) async {
setState(() => isSuggested = suggested);
if (room != null) {
await showFutureLoadingDialog(
context: context,
future: () async => await room?.setSuggested(suggested),
);
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final String title = widget.mode == AddToClassMode.exchange final String title = widget.mode == AddToClassMode.exchange
@ -292,9 +221,28 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
const Divider(height: 1), const Divider(height: 1),
possibleParents.isNotEmpty possibleParents.isNotEmpty
? Column( ? Column(
children: possibleParents children: [
.mapIndexed((index, _) => getAddToSpaceToggleItem(index)) SwitchListTile.adaptive(
.toList(), title: Text(L10n.of(context)!.suggestToChat),
secondary: Icon(
isSuggested
? Icons.visibility_outlined
: Icons.visibility_off_outlined,
),
subtitle: Text(L10n.of(context)!.suggestToChatDesc),
activeColor: AppConfig.activeToggleColor,
value: isSuggested,
onChanged: (bool add) => setSuggested(add),
),
Divider(
height: 0.5,
color:
Theme.of(context).colorScheme.secondary.withAlpha(25),
),
...possibleParents.mapIndexed(
(index, _) => getAddToSpaceToggleItem(index),
),
],
) )
: Center( : Center(
child: Padding( child: Padding(
@ -312,10 +260,3 @@ class AddToSpaceState extends State<AddToSpaceToggles> {
); );
} }
} }
class SuggestionStatus {
bool suggested;
final Room room;
SuggestionStatus(this.suggested, this.room);
}

Loading…
Cancel
Save