ideal case of private class code
This commit is contained in:
parent
dfb45bb20e
commit
550c3ab699
5 changed files with 83 additions and 40 deletions
|
|
@ -150,7 +150,10 @@ class NewSpaceController extends State<NewSpace> {
|
|||
try {
|
||||
final avatar = this.avatar;
|
||||
avatarUrl ??= avatar == null ? null : await client.uploadContent(avatar);
|
||||
|
||||
final classCode = await SpaceCodeUtil.generateSpaceCode(client);
|
||||
if (classCode == null) {
|
||||
return;
|
||||
}
|
||||
final spaceId = await client.createRoom(
|
||||
// #Pangea
|
||||
// preset: publicGroup
|
||||
|
|
@ -164,7 +167,7 @@ class NewSpaceController extends State<NewSpace> {
|
|||
// roomAliasName: publicGroup
|
||||
// ? nameController.text.trim().toLowerCase().replaceAll(' ', '_')
|
||||
// : null,
|
||||
roomAliasName: SpaceCodeUtil.generateSpaceCode(),
|
||||
roomAliasName: classCode,
|
||||
// Pangea#
|
||||
name: nameController.text.trim(),
|
||||
topic: topicController.text.isEmpty ? null : topicController.text,
|
||||
|
|
@ -178,14 +181,21 @@ class NewSpaceController extends State<NewSpace> {
|
|||
: null,
|
||||
// Pangea#
|
||||
initialState: [
|
||||
// #Pangea
|
||||
...initialState,
|
||||
// Pangea#
|
||||
if (avatar != null)
|
||||
sdk.StateEvent(
|
||||
type: sdk.EventTypes.RoomAvatar,
|
||||
content: {'url': avatarUrl.toString()},
|
||||
),
|
||||
// #Pangea
|
||||
...initialState,
|
||||
// Pangea#
|
||||
sdk.StateEvent(
|
||||
type: sdk.EventTypes.RoomJoinRules,
|
||||
content: {
|
||||
'join_rule': 'knock',
|
||||
'access_code': classCode,
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
// #Pangea
|
||||
|
|
|
|||
|
|
@ -123,4 +123,8 @@ class ModelKey {
|
|||
|
||||
static const String prevEventId = "prev_event_id";
|
||||
static const String prevLastUpdated = "prev_last_updated";
|
||||
|
||||
// room code
|
||||
static const String joinRule = "join_rule";
|
||||
static const String accessCode = "access_code";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fluffychat/pangea/constants/local.key.dart';
|
||||
import 'package:fluffychat/pangea/constants/pangea_event_types.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
|
|
@ -9,15 +9,15 @@ import 'package:fluffychat/pangea/extensions/client_extension/client_extension.d
|
|||
import 'package:fluffychat/pangea/extensions/pangea_room_extension/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/models/space_model.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
||||
import 'package:fluffychat/pangea/utils/space_code.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
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:matrix/matrix.dart';
|
||||
|
||||
import '../../widgets/matrix.dart';
|
||||
import '../utils/firebase_analytics.dart';
|
||||
import 'base_controller.dart';
|
||||
|
||||
class ClassController extends BaseController {
|
||||
|
|
@ -65,47 +65,56 @@ class ClassController extends BaseController {
|
|||
}
|
||||
|
||||
Future<void> joinClasswithCode(BuildContext context, String classCode) async {
|
||||
final client = Matrix.of(context).client;
|
||||
try {
|
||||
final QueryPublicRoomsResponse queryPublicRoomsResponse =
|
||||
await Matrix.of(context).client.queryPublicRooms(
|
||||
limit: 1,
|
||||
filter: PublicRoomQueryFilter(genericSearchTerm: classCode),
|
||||
);
|
||||
|
||||
final PublicRoomsChunk? classChunk =
|
||||
queryPublicRoomsResponse.chunk.firstWhereOrNull((element) {
|
||||
return element.canonicalAlias?.replaceAll("#", "").split(":")[0] ==
|
||||
classCode;
|
||||
});
|
||||
|
||||
if (classChunk == null) {
|
||||
final knockResponse = await client.httpClient.post(
|
||||
Uri.parse(
|
||||
'${client.homeserver}/_synapse/client/pangea/v1/knock_with_code',
|
||||
),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ${client.accessToken}',
|
||||
},
|
||||
body: jsonEncode({'access_code': classCode}),
|
||||
);
|
||||
if (knockResponse.statusCode != 200) {
|
||||
SpaceCodeUtil.messageSnack(
|
||||
context,
|
||||
L10n.of(context)!.unableToFindClass,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final knockResult = jsonDecode(knockResponse.body);
|
||||
final foundClasses = knockResult['rooms'];
|
||||
if (!(foundClasses is List<String> && foundClasses.isNotEmpty)) {
|
||||
SpaceCodeUtil.messageSnack(
|
||||
context,
|
||||
L10n.of(context)!.unableToFindClass,
|
||||
);
|
||||
return;
|
||||
}
|
||||
final chosenClassId = foundClasses.first;
|
||||
await client.joinRoomById(chosenClassId);
|
||||
if (_pangeaController.matrixState.client.rooms
|
||||
.any((room) => room.id == classChunk.roomId)) {
|
||||
setActiveSpaceIdInChatListController(classChunk.roomId);
|
||||
.any((room) => room.id == chosenClassId)) {
|
||||
setActiveSpaceIdInChatListController(chosenClassId);
|
||||
SpaceCodeUtil.messageSnack(context, L10n.of(context)!.alreadyInClass);
|
||||
return;
|
||||
}
|
||||
|
||||
await _pangeaController.matrixState.client.joinRoom(classChunk.roomId);
|
||||
await _pangeaController.matrixState.client.joinRoom(chosenClassId);
|
||||
|
||||
if (_pangeaController.matrixState.client.getRoomById(classChunk.roomId) ==
|
||||
if (_pangeaController.matrixState.client.getRoomById(chosenClassId) ==
|
||||
null) {
|
||||
await _pangeaController.matrixState.client.waitForRoomInSync(
|
||||
classChunk.roomId,
|
||||
chosenClassId,
|
||||
join: true,
|
||||
);
|
||||
}
|
||||
|
||||
// If the room is full, leave
|
||||
final room =
|
||||
_pangeaController.matrixState.client.getRoomById(classChunk.roomId);
|
||||
_pangeaController.matrixState.client.getRoomById(chosenClassId);
|
||||
if (room == null) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -121,12 +130,12 @@ class ClassController extends BaseController {
|
|||
return;
|
||||
}
|
||||
|
||||
setActiveSpaceIdInChatListController(classChunk.roomId);
|
||||
setActiveSpaceIdInChatListController(chosenClassId);
|
||||
|
||||
// add the user's analytics room to this joined space
|
||||
// so their teachers can join them via the space hierarchy
|
||||
final Room? joinedSpace =
|
||||
_pangeaController.matrixState.client.getRoomById(classChunk.roomId);
|
||||
_pangeaController.matrixState.client.getRoomById(chosenClassId);
|
||||
|
||||
// when possible, add user's analytics room the to space they joined
|
||||
joinedSpace?.addAnalyticsRoomsToSpace();
|
||||
|
|
|
|||
|
|
@ -15,8 +15,14 @@ extension SpaceRoomExtension on Room {
|
|||
}
|
||||
return "Not in a class!";
|
||||
}
|
||||
|
||||
return canonicalAlias.replaceAll(":$domainString", "").replaceAll("#", "");
|
||||
final roomJoinRules = getState(EventTypes.RoomJoinRules, "");
|
||||
if (roomJoinRules != null) {
|
||||
final accessCode = roomJoinRules.content.tryGet(ModelKey.accessCode);
|
||||
if (accessCode is String) {
|
||||
return accessCode;
|
||||
}
|
||||
}
|
||||
return "No class code!";
|
||||
}
|
||||
|
||||
void _checkClass() {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import 'dart:math';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
||||
import '../controllers/pangea_controller.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
class SpaceCodeUtil {
|
||||
static const codeLength = 6;
|
||||
|
|
@ -13,11 +13,25 @@ class SpaceCodeUtil {
|
|||
return spacecode == null || spacecode.length > 4;
|
||||
}
|
||||
|
||||
static String generateSpaceCode() {
|
||||
final r = Random();
|
||||
const chars = 'AaBbCcDdEeFfGgHhiJjKkLMmNnoPpQqRrSsTtUuVvWwXxYyZz1234567890';
|
||||
return List.generate(codeLength, (index) => chars[r.nextInt(chars.length)])
|
||||
.join();
|
||||
static Future<String?> generateSpaceCode(Client client) async {
|
||||
final response = await client.httpClient.get(
|
||||
Uri.parse(
|
||||
'${client.homeserver}/_synapse/client/pangea/v1/request_room_code',
|
||||
),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer ${client.accessToken}',
|
||||
},
|
||||
);
|
||||
if (response.statusCode != 200) {
|
||||
return null;
|
||||
}
|
||||
final roomCodeResult = jsonDecode(response.body);
|
||||
if (roomCodeResult['access_code'] is String) {
|
||||
return roomCodeResult['access_code'] as String;
|
||||
} else {
|
||||
throw Exception('Invalid response, access_code not found $response');
|
||||
}
|
||||
}
|
||||
|
||||
static Future<void> joinWithSpaceCodeDialog(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue