remove space code controller from pangea controller

This commit is contained in:
ggurdin 2025-12-03 16:36:41 -05:00
parent e184e9a76f
commit 97bfdb2603
No known key found for this signature in database
GPG key ID: A01CB41737CBB478
40 changed files with 211 additions and 631 deletions

View file

@ -53,8 +53,8 @@ import 'package:fluffychat/pangea/login/pages/new_course_page.dart';
import 'package:fluffychat/pangea/login/pages/public_courses_page.dart';
import 'package:fluffychat/pangea/login/pages/signup.dart';
import 'package:fluffychat/pangea/space_analytics/space_analytics.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/utils/join_with_link.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
import 'package:fluffychat/pangea/spaces/widgets/join_with_link_page.dart';
import 'package:fluffychat/pangea/subscription/pages/settings_subscription.dart';
import 'package:fluffychat/widgets/config_viewer.dart';
import 'package:fluffychat/widgets/layouts/empty_page.dart';

View file

@ -45,6 +45,7 @@ void main() async {
final List<Future> initFutures = [
GetStorage.init(),
GetStorage.init("subscription_storage"),
GetStorage.init('class_storage'),
];
await Future.wait(initFutures);
// Pangea#

View file

@ -62,7 +62,7 @@ import 'package:fluffychat/pangea/learning_settings/constants/language_constants
import 'package:fluffychat/pangea/learning_settings/repo/language_mismatch_repo.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dialog.dart';
import 'package:fluffychat/pangea/message_token_text/tokens_util.dart';
import 'package:fluffychat/pangea/spaces/utils/load_participants_util.dart';
import 'package:fluffychat/pangea/spaces/widgets/load_participants_builder.dart';
import 'package:fluffychat/pangea/subscription/widgets/paywall_card.dart';
import 'package:fluffychat/pangea/token_info_feedback/token_info_feedback_dialog.dart';
import 'package:fluffychat/pangea/token_info_feedback/token_info_feedback_notification.dart';

View file

@ -20,6 +20,8 @@ import 'package:fluffychat/pangea/chat_settings/constants/pangea_room_types.dart
import 'package:fluffychat/pangea/chat_settings/widgets/chat_context_menu_action.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/spaces/space_code_controller.dart';
import 'package:fluffychat/pangea/spaces/space_code_repo.dart';
import 'package:fluffychat/pangea/subscription/widgets/subscription_snackbar.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
@ -40,6 +42,7 @@ import '../../widgets/matrix.dart';
import 'package:fluffychat/utils/tor_stub.dart'
if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart';
enum PopupMenuAction {
settings,
invite,
@ -587,10 +590,8 @@ class ChatListController extends State<ChatList>
spaceId,
);
final String? justInputtedCode =
MatrixState.pangeaController.spaceCodeController.justInputtedCode;
final newSpaceCode = space?.classCode;
if (newSpaceCode?.toLowerCase() == justInputtedCode?.toLowerCase()) {
if (space?.classCode?.toLowerCase() ==
SpaceCodeRepo.recentCode?.toLowerCase()) {
return;
}
@ -700,8 +701,7 @@ class ChatListController extends State<ChatList>
_roomCapacitySubscription?.cancel();
MatrixState.pangeaController.subscriptionController.subscriptionNotifier
.removeListener(_onSubscribe);
MatrixState.pangeaController.spaceCodeController.codeNotifier
.removeListener(_onCacheSpaceCode);
SpaceCodeController.codeNotifier.removeListener(_onCacheSpaceCode);
//Pangea#
scrollController.removeListener(_onScroll);
super.dispose();
@ -1112,18 +1112,14 @@ class ChatListController extends State<ChatList>
void _initPangeaControllers(Client client) {
MatrixState.pangeaController.initControllers();
if (mounted) {
MatrixState.pangeaController.spaceCodeController
.joinCachedSpaceCode(context);
MatrixState.pangeaController.spaceCodeController.codeNotifier
.addListener(_onCacheSpaceCode);
SpaceCodeController.joinCachedSpaceCode(context);
SpaceCodeController.codeNotifier.addListener(_onCacheSpaceCode);
}
}
void _onCacheSpaceCode() {
if (!mounted) return;
MatrixState.pangeaController.spaceCodeController.joinCachedSpaceCode(
context,
);
SpaceCodeController.joinCachedSpaceCode(context);
}
// Pangea#

View file

@ -6,7 +6,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/activity_planner/activity_plan_model.dart';
import 'package:fluffychat/pangea/activity_sessions/activity_participant_indicator.dart';
import 'package:fluffychat/pangea/activity_sessions/activity_role_model.dart';
import 'package:fluffychat/pangea/spaces/utils/load_participants_util.dart';
import 'package:fluffychat/pangea/spaces/widgets/load_participants_builder.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';

View file

@ -5,6 +5,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/spaces/space_code_repo.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
@ -116,8 +117,7 @@ void chatListHandleSpaceTap(
(element) =>
element.isSpace && element.membership == Membership.join,
);
final justInputtedCode =
MatrixState.pangeaController.spaceCodeController.justInputtedCode;
final justInputtedCode = SpaceCodeRepo.recentCode;
if (rooms.any((s) => s.spaceChildren.any((c) => c.roomId == space.id))) {
autoJoin(space);
} else if (justInputtedCode != null &&

View file

@ -16,7 +16,7 @@ import 'package:fluffychat/pangea/chat_settings/pages/pangea_invitation_selectio
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/course_plans/map_clipper.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
import 'package:fluffychat/utils/stream_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/user_dialog.dart';
import 'package:fluffychat/widgets/avatar.dart';

View file

@ -8,7 +8,7 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/analytics_misc/level_display_name.dart';
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
import 'package:fluffychat/pangea/spaces/utils/load_participants_util.dart';
import 'package:fluffychat/pangea/spaces/widgets/load_participants_builder.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';

View file

@ -19,7 +19,7 @@ import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'
import 'package:fluffychat/pangea/events/repo/token_api_models.dart';
import 'package:fluffychat/pangea/events/repo/tokens_repo.dart';
import 'package:fluffychat/pangea/learning_settings/constants/language_constants.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/learning_settings/enums/tool_settings_enum.dart';
import 'package:fluffychat/pangea/subscription/controllers/subscription_controller.dart';
import 'package:fluffychat/pangea/text_to_speech/tts_controller.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';

View file

@ -20,7 +20,6 @@ import 'package:fluffychat/pangea/guard/p_vguard.dart';
import 'package:fluffychat/pangea/learning_settings/controllers/language_controller.dart';
import 'package:fluffychat/pangea/learning_settings/utils/locale_provider.dart';
import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart';
import 'package:fluffychat/pangea/spaces/controllers/space_code_controller.dart';
import 'package:fluffychat/pangea/subscription/controllers/subscription_controller.dart';
import 'package:fluffychat/pangea/text_to_speech/tts_controller.dart';
import 'package:fluffychat/pangea/user/controllers/permissions_controller.dart';
@ -32,7 +31,6 @@ class PangeaController {
///pangeaControllers
late UserController userController;
late LanguageController languageController;
late SpaceCodeController spaceCodeController;
late PermissionsController permissionsController;
late GetAnalyticsController getAnalytics;
late PutAnalyticsController putAnalytics;
@ -75,7 +73,6 @@ class PangeaController {
_addRefInObjects() {
userController = UserController(this);
languageController = LanguageController(this);
spaceCodeController = SpaceCodeController(this);
permissionsController = PermissionsController(this);
getAnalytics = GetAnalyticsController(this);
putAnalytics = PutAnalyticsController(this);
@ -300,39 +297,4 @@ class PangeaController {
);
}
}
// /// Joins the user to the support space if they are
// /// not already a member and have not previously left.
// Future<void> joinSupportSpace() async {
// // if the user is already in the space, return
// await matrixState.client.roomsLoading;
// final isInSupportSpace = matrixState.client.rooms.any(
// (room) => room.id == Environment.supportSpaceId,
// );
// if (isInSupportSpace) return;
// // if the user has previously joined the space, return
// final bool previouslyJoined =
// userController.profile.userSettings.hasJoinedHelpSpace ?? false;
// if (previouslyJoined) return;
// // join the space
// try {
// await matrixState.client.joinRoomById(Environment.supportSpaceId);
// final room = matrixState.client.getRoomById(Environment.supportSpaceId);
// if (room == null) {
// await matrixState.client.waitForRoomInSync(
// Environment.supportSpaceId,
// join: true,
// );
// }
// userController.updateProfile((profile) {
// profile.userSettings.hasJoinedHelpSpace = true;
// return profile;
// });
// } catch (err, s) {
// ErrorHandler.logError(e: err, s: s);
// return;
// }
// }
}

View file

@ -9,7 +9,7 @@ import 'package:universal_html/html.dart' as html;
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
class ShareRoomButton extends StatelessWidget {
final Room room;

View file

@ -21,7 +21,7 @@ import 'package:fluffychat/pangea/course_plans/courses/course_plan_builder.dart'
import 'package:fluffychat/pangea/course_plans/courses/course_plan_room_extension.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/public_spaces/public_room_bottom_sheet.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
import 'package:fluffychat/utils/localized_exception_extension.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/adaptive_dialog_action.dart';

View file

@ -1,5 +1,5 @@
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
enum CourseDefaultChatsEnum {
introductions,

View file

@ -15,7 +15,7 @@ import 'package:fluffychat/pangea/course_plans/courses/course_plan_event.dart';
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
import 'package:fluffychat/pangea/extensions/join_rule_extension.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
extension CoursePlanRoomExtension on Room {
CoursePlanEvent? get coursePlan {

View file

@ -6,7 +6,7 @@ import 'package:collection/collection.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/spaces/utils/load_participants_util.dart';
import 'package:fluffychat/pangea/spaces/widgets/load_participants_builder.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';

View file

@ -18,8 +18,8 @@ import 'package:fluffychat/pangea/events/repo/language_detection_repo.dart';
import 'package:fluffychat/pangea/events/repo/language_detection_request.dart';
import 'package:fluffychat/pangea/events/repo/language_detection_response.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/learning_settings/enums/tool_settings_enum.dart';
import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/speech_to_text/audio_encoding_enum.dart';
import 'package:fluffychat/pangea/speech_to_text/speech_to_text_repo.dart';
import 'package:fluffychat/pangea/speech_to_text/speech_to_text_request_model.dart';

View file

@ -2,7 +2,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/spaces/utils/space_code.dart';
import 'package:fluffychat/pangea/spaces/utils/space_code_extension.dart';
extension JoinRuleExtension on Client {
Future<StateEvent> pangeaJoinRules(
@ -11,7 +11,7 @@ extension JoinRuleExtension on Client {
}) async {
String? joinCode;
try {
joinCode = await SpaceCodeUtil.generateSpaceCode(this);
joinCode = await requestSpaceCode();
} catch (e, s) {
ErrorHandler.logError(
e: e,
@ -42,7 +42,7 @@ extension JoinRuleExtensionOnRoom on Room {
final currentJoinRules = getState(EventTypes.RoomJoinRules)?.content ?? {};
if (currentJoinRules[ModelKey.accessCode] != null) return;
final joinCode = await SpaceCodeUtil.generateSpaceCode(client);
final joinCode = await client.requestSpaceCode();
currentJoinRules[ModelKey.accessCode] = joinCode;
await client.setRoomStateWithKey(

View file

@ -31,7 +31,7 @@ import 'package:fluffychat/pangea/events/models/tokens_event_content_model.dart'
import 'package:fluffychat/pangea/extensions/join_rule_extension.dart';
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
import 'package:fluffychat/pangea/lemmas/user_set_lemma_info.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_text_input_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import '../choreographer/choreo_record_model.dart';

View file

@ -2,7 +2,7 @@ import 'dart:math';
import 'package:matrix/matrix_api_lite/generated/model.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
extension PangeaRoomsChunk on PublicRoomsChunk {
/// Use Random with a seed to get the default

View file

@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/widgets/matrix.dart';
enum ToolSetting {
interactiveTranslator,
interactiveGrammar,
immersionMode,
definitions,
autoIGC,
enableTTS,
enableAutocorrect;
String toolName(BuildContext context) {
switch (this) {
case ToolSetting.interactiveTranslator:
return L10n.of(context).interactiveTranslatorSliderHeader;
case ToolSetting.interactiveGrammar:
return L10n.of(context).interactiveGrammarSliderHeader;
case ToolSetting.immersionMode:
return L10n.of(context).toggleImmersionMode;
case ToolSetting.definitions:
return L10n.of(context).definitionsToolName;
case ToolSetting.autoIGC:
return L10n.of(context).autoIGCToolName;
case ToolSetting.enableTTS:
return L10n.of(context).enableTTSToolName;
case ToolSetting.enableAutocorrect:
return L10n.of(context).enableAutocorrectToolName;
}
}
//use l10n to get tool name
String toolDescription(BuildContext context) {
switch (this) {
case ToolSetting.interactiveTranslator:
return L10n.of(context).itToggleDescription;
case ToolSetting.interactiveGrammar:
return L10n.of(context).igcToggleDescription;
case ToolSetting.immersionMode:
return L10n.of(context).toggleImmersionModeDesc;
case ToolSetting.definitions:
return L10n.of(context).definitionsToolDescription;
case ToolSetting.autoIGC:
return L10n.of(context).autoIGCToolDescription;
case ToolSetting.enableTTS:
return L10n.of(context).enableTTSToolDescription;
case ToolSetting.enableAutocorrect:
return L10n.of(context).enableAutocorrectDescription;
}
}
bool get isAvailableSetting {
switch (this) {
case ToolSetting.interactiveTranslator:
case ToolSetting.interactiveGrammar:
case ToolSetting.definitions:
case ToolSetting.immersionMode:
return false;
case ToolSetting.autoIGC:
case ToolSetting.enableTTS:
case ToolSetting.enableAutocorrect:
return true;
}
}
bool get enabled =>
MatrixState.pangeaController.permissionsController.isToolEnabled(this);
}

View file

@ -10,10 +10,10 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/instructions/instruction_settings.dart';
import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart';
import 'package:fluffychat/pangea/learning_settings/enums/tool_settings_enum.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning_view.dart';
import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/text_to_speech/tts_controller.dart';
import 'package:fluffychat/pangea/user/models/user_model.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';

View file

@ -13,12 +13,12 @@ import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/common/widgets/full_width_dialog.dart';
import 'package:fluffychat/pangea/instructions/reset_instructions_list_tile.dart';
import 'package:fluffychat/pangea/learning_settings/enums/tool_settings_enum.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/learning_settings/pages/settings_learning.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/country_picker_tile.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/p_language_dropdown.dart';
import 'package:fluffychat/pangea/learning_settings/widgets/p_settings_switch_list_tile.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
import 'package:fluffychat/widgets/matrix.dart';

View file

@ -6,6 +6,7 @@ import 'package:go_router/go_router.dart';
import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/login/pages/add_course_page.dart';
import 'package:fluffychat/pangea/spaces/space_code_controller.dart';
import 'package:fluffychat/widgets/matrix.dart';
class CourseCodePage extends StatefulWidget {
@ -39,8 +40,7 @@ class CourseCodePageState extends State<CourseCodePage> {
return;
}
final roomId = await MatrixState.pangeaController.spaceCodeController
.joinSpaceWithCode(
final roomId = await SpaceCodeController.joinSpaceWithCode(
context,
_code,
);

View file

@ -15,6 +15,8 @@ import 'package:fluffychat/pangea/course_plans/courses/course_plans_repo.dart';
import 'package:fluffychat/pangea/course_plans/courses/get_localized_courses_request.dart';
import 'package:fluffychat/pangea/learning_settings/utils/p_language_store.dart';
import 'package:fluffychat/pangea/login/utils/lang_code_repo.dart';
import 'package:fluffychat/pangea/spaces/space_code_controller.dart';
import 'package:fluffychat/pangea/spaces/space_code_repo.dart';
import 'package:fluffychat/widgets/matrix.dart';
class CreatePangeaAccountPage extends StatefulWidget {
@ -52,8 +54,7 @@ class CreatePangeaAccountPageState extends State<CreatePangeaAccountPage> {
(await _cachedLangCode)?.baseLangCode ??
MatrixState.pangeaController.languageController.systemLanguage?.langCode;
String? get _cachedSpaceCode =>
MatrixState.pangeaController.spaceCodeController.cachedSpaceCode;
String? get _cachedSpaceCode => SpaceCodeRepo.spaceCode;
Future<void> _createProfile() async {
setState(() {
@ -72,13 +73,10 @@ class CreatePangeaAccountPageState extends State<CreatePangeaAccountPage> {
}
Future<void> _joinCachedCourse() async {
await MatrixState.pangeaController.spaceCodeController.initCompleter.future;
if (_cachedSpaceCode == null) return;
try {
final spaceId = await MatrixState.pangeaController.spaceCodeController
.joinCachedSpaceCode(context);
final spaceId = await SpaceCodeController.joinCachedSpaceCode(context);
if (spaceId == null) {
throw Exception('Failed to join space with code $_cachedSpaceCode');
}

View file

@ -7,7 +7,7 @@ import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/config/environment.dart';
import 'package:fluffychat/pangea/common/widgets/pangea_logo_svg.dart';
import 'package:fluffychat/pangea/login/widgets/app_config_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/pangea/spaces/space_code_repo.dart';
class LoginOrSignupView extends StatefulWidget {
const LoginOrSignupView({super.key});
@ -25,8 +25,7 @@ class LoginOrSignupViewState extends State<LoginOrSignupView> {
_loadOverrides();
}
String? get _cachedSpaceCode =>
MatrixState.pangeaController.spaceCodeController.cachedSpaceCode;
String? get _cachedSpaceCode => SpaceCodeRepo.spaceCode;
Future<void> _loadOverrides() async {
final overrides = await Environment.getAppConfigOverrides();

View file

@ -7,6 +7,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/extensions/pangea_rooms_chunk_extension.dart';
import 'package:fluffychat/pangea/spaces/space_code_controller.dart';
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
@ -83,8 +84,7 @@ class PublicRoomBottomSheetState extends State<PublicRoomBottomSheet> {
bool get _isKnockRoom => widget.chunk?.joinRule == 'knock';
Future<void> _joinWithCode() async {
final resp = await MatrixState.pangeaController.spaceCodeController
.joinSpaceWithCode(
final resp = await SpaceCodeController.joinSpaceWithCode(
context,
_codeController.text,
notFoundError: L10n.of(context).notTheCodeError,

View file

@ -8,9 +8,9 @@ import 'package:material_symbols_icons/symbols.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/widgets/dropdown_text_button.dart';
import 'package:fluffychat/pangea/learning_settings/models/language_model.dart';
import 'package:fluffychat/pangea/space_analytics/download_space_analytics_dialog.dart';
import 'package:fluffychat/pangea/space_analytics/space_analytics.dart';
import 'package:fluffychat/pangea/space_analytics/space_analytics_download_enum.dart';
import 'package:fluffychat/pangea/spaces/widgets/download_space_analytics_dialog.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/layouts/max_width_body.dart';

View file

@ -1,299 +0,0 @@
import 'dart:developer';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../events/constants/pangea_event_types.dart';
import '../../learning_settings/constants/language_constants.dart';
import '../../learning_settings/models/language_model.dart';
class LanguageSettingsModel {
String? city;
String? country;
String? schoolName;
String dominantLanguage;
String targetLanguage;
LanguageSettingsModel({
this.dominantLanguage = SpaceConstants.defaultDominantLanguage,
this.targetLanguage = SpaceConstants.defaultTargetLanguage,
this.city,
this.country,
this.schoolName,
});
factory LanguageSettingsModel.fromJson(Map<String, dynamic> json) {
return LanguageSettingsModel(
city: json['city'],
country: json['country'],
dominantLanguage: LanguageModel.codeFromNameOrCode(
json['dominant_language'] ?? LanguageKeys.unknownLanguage,
),
targetLanguage: LanguageModel.codeFromNameOrCode(
json['target_language'] ?? LanguageKeys.unknownLanguage,
),
schoolName: json['school_name'],
);
}
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
try {
data['city'] = city;
data['country'] = country;
//check for and do "english" => en and "spanish" => es
data['dominant_language'] = dominantLanguage;
//check for and do "english" => en and "spanish" => es
data['target_language'] = targetLanguage;
data['school_name'] = schoolName;
return data;
} catch (e, s) {
debugger(when: kDebugMode);
ErrorHandler.logError(
e: e,
s: s,
data: data,
);
return data;
}
}
StateEvent get toStateEvent => StateEvent(
content: toJson(),
type: PangeaEventTypes.languageSettings,
);
}
class PangeaRoomRules {
// int? pangeaClassID; // this is id our database
bool isPublic;
bool isOpenEnrollment;
bool oneToOneChatClass;
bool isCreateRooms;
bool isShareVideo;
bool isSharePhoto;
bool isShareFiles;
bool isShareLocation;
bool isCreateStories;
bool isVoiceNotes;
bool isInviteOnlyStudents;
// 0 = forbidden, 1 = allow individual to choose, 2 = require
int interactiveTranslator;
int interactiveGrammar;
int immersionMode;
int definitions;
int translations;
int autoIGC;
PangeaRoomRules({
this.isPublic = false,
this.isOpenEnrollment = false,
this.oneToOneChatClass = true,
this.isCreateRooms = true,
this.isShareVideo = true,
this.isSharePhoto = true,
this.isShareFiles = true,
this.isShareLocation = false,
this.isCreateStories = false,
this.isVoiceNotes = true,
this.isInviteOnlyStudents = true,
this.interactiveTranslator = SpaceConstants.languageToolPermissions,
this.interactiveGrammar = SpaceConstants.languageToolPermissions,
this.immersionMode = SpaceConstants.languageToolPermissions,
this.definitions = SpaceConstants.languageToolPermissions,
this.translations = SpaceConstants.languageToolPermissions,
this.autoIGC = SpaceConstants.languageToolPermissions,
});
setLanguageToolSetting(ToolSetting setting, int value) {
switch (setting) {
case ToolSetting.interactiveTranslator:
interactiveTranslator = value;
break;
case ToolSetting.interactiveGrammar:
interactiveGrammar = value;
break;
case ToolSetting.immersionMode:
immersionMode = value;
break;
case ToolSetting.definitions:
definitions = value;
break;
// case ToolSetting.translations:
// translations = value;
// break;
case ToolSetting.autoIGC:
autoIGC = value;
break;
default:
throw Exception('Invalid key for setting permissions - $setting');
}
}
StateEvent get toStateEvent => StateEvent(
content: toJson(),
type: PangeaEventTypes.rules,
);
factory PangeaRoomRules.fromJson(Map<String, dynamic> json) =>
PangeaRoomRules(
// pangeaClassID: json['pangea_class'];
isPublic: json['is_public'],
isOpenEnrollment: json['is_open_enrollment'],
oneToOneChatClass: json['one_to_one_chat_class'],
isCreateRooms: json['is_create_rooms'],
isShareVideo: json['is_share_video'],
isSharePhoto: json['is_share_photo'],
isShareFiles: json['is_share_files'],
isShareLocation: json['is_share_location'],
isCreateStories: json['is_create_stories'],
isVoiceNotes: json['is_voice_notes'],
isInviteOnlyStudents: json['is_invite_only_students'] ?? true,
interactiveTranslator: json['interactive_translator'] ??
SpaceConstants.languageToolPermissions,
interactiveGrammar: json['interactive_grammar'] ??
SpaceConstants.languageToolPermissions,
immersionMode:
json['immersion_mode'] ?? SpaceConstants.languageToolPermissions,
definitions:
json['definitions'] ?? SpaceConstants.languageToolPermissions,
translations:
json['translations'] ?? SpaceConstants.languageToolPermissions,
autoIGC: json['auto_igc'] ?? SpaceConstants.languageToolPermissions,
);
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
// data['pangea_class'] = pangeaClassID;
data['is_public'] = isPublic;
data['is_open_enrollment'] = isOpenEnrollment;
data['one_to_one_chat_class'] = oneToOneChatClass;
data['is_create_rooms'] = isCreateRooms;
data['is_share_video'] = isShareVideo;
data['is_share_photo'] = isSharePhoto;
data['is_share_files'] = isShareFiles;
data['is_share_location'] = isShareLocation;
data['is_create_stories'] = isCreateStories;
data['is_voice_notes'] = isVoiceNotes;
data['is_invite_only_students'] = isInviteOnlyStudents;
data['interactive_translator'] = interactiveTranslator;
data['interactive_grammar'] = interactiveGrammar;
data['immersion_mode'] = immersionMode;
data['definitions'] = definitions;
data['translations'] = translations;
data['auto_igc'] = autoIGC;
return data;
}
int getToolSettings(ToolSetting setting) {
switch (setting) {
case ToolSetting.interactiveTranslator:
return interactiveTranslator;
case ToolSetting.interactiveGrammar:
return interactiveGrammar;
case ToolSetting.immersionMode:
return immersionMode;
case ToolSetting.definitions:
return definitions;
// case ToolSetting.translations:
// return translations;
case ToolSetting.autoIGC:
return autoIGC;
default:
throw Exception('Invalid key for setting permissions - $setting');
}
}
String languageToolPermissionsText(
BuildContext context,
ToolSetting setting,
) {
switch (getToolSettings(setting)) {
case 0:
return L10n.of(context).interactiveTranslatorNotAllowed;
case 1:
return L10n.of(context).interactiveTranslatorAllowed;
case 2:
return L10n.of(context).interactiveTranslatorRequired;
default:
return L10n.of(context).notYetSet;
}
}
}
enum ToolSetting {
interactiveTranslator,
interactiveGrammar,
immersionMode,
definitions,
// translations,
autoIGC,
enableTTS,
enableAutocorrect;
String toolName(BuildContext context) {
switch (this) {
case ToolSetting.interactiveTranslator:
return L10n.of(context).interactiveTranslatorSliderHeader;
case ToolSetting.interactiveGrammar:
return L10n.of(context).interactiveGrammarSliderHeader;
case ToolSetting.immersionMode:
return L10n.of(context).toggleImmersionMode;
case ToolSetting.definitions:
return L10n.of(context).definitionsToolName;
// case ToolSetting.translations:
// return L10n.of(context).messageTranslationsToolName;
case ToolSetting.autoIGC:
return L10n.of(context).autoIGCToolName;
case ToolSetting.enableTTS:
return L10n.of(context).enableTTSToolName;
case ToolSetting.enableAutocorrect:
return L10n.of(context).enableAutocorrectToolName;
}
}
//use l10n to get tool name
String toolDescription(BuildContext context) {
switch (this) {
case ToolSetting.interactiveTranslator:
return L10n.of(context).itToggleDescription;
case ToolSetting.interactiveGrammar:
return L10n.of(context).igcToggleDescription;
case ToolSetting.immersionMode:
return L10n.of(context).toggleImmersionModeDesc;
case ToolSetting.definitions:
return L10n.of(context).definitionsToolDescription;
// case ToolSetting.translations:
// return L10n.of(context).translationsToolDescrption;
case ToolSetting.autoIGC:
return L10n.of(context).autoIGCToolDescription;
case ToolSetting.enableTTS:
return L10n.of(context).enableTTSToolDescription;
case ToolSetting.enableAutocorrect:
return L10n.of(context).enableAutocorrectDescription;
}
}
bool get isAvailableSetting {
switch (this) {
case ToolSetting.interactiveTranslator:
case ToolSetting.interactiveGrammar:
case ToolSetting.definitions:
case ToolSetting.immersionMode:
return false;
case ToolSetting.autoIGC:
case ToolSetting.enableTTS:
case ToolSetting.enableAutocorrect:
return true;
}
}
bool get enabled =>
MatrixState.pangeaController.permissionsController.isToolEnabled(this);
}

View file

@ -5,85 +5,61 @@ import 'dart:async';
import 'package:flutter/material.dart';
import 'package:collection/collection.dart';
import 'package:get_storage/get_storage.dart';
import 'package:go_router/go_router.dart';
import 'package:http/http.dart';
import 'package:http/http.dart' hide Client;
import 'package:matrix/matrix.dart';
import 'package:fluffychat/l10n/l10n.dart';
import 'package:fluffychat/pangea/common/constants/local.key.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/spaces/constants/space_constants.dart';
import 'package:fluffychat/pangea/spaces/space_code_repo.dart';
import 'package:fluffychat/pangea/spaces/space_constants.dart';
import 'package:fluffychat/pangea/spaces/utils/knock_space_extension.dart';
import 'package:fluffychat/pangea/spaces/widgets/too_many_requests_dialog.dart';
import 'package:fluffychat/widgets/future_loading_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../common/controllers/base_controller.dart';
import '../common/controllers/base_controller.dart';
class NotFoundException implements Exception {}
class SpaceCodeController extends BaseController {
late PangeaController _pangeaController;
static final GetStorage _spaceStorage = GetStorage('class_storage');
static ValueNotifier<String?> codeNotifier = ValueNotifier<String?>(null);
Completer<void> initCompleter = Completer<void>();
ValueNotifier<String?> codeNotifier = ValueNotifier<String?>(null);
SpaceCodeController(PangeaController pangeaController) : super() {
_pangeaController = pangeaController;
GetStorage.init('class_storage').then(
(_) => initCompleter.complete(),
);
static Future<void> onOpenAppViaUrl(Uri url) async {
if (url.fragment.isEmpty) return;
final fragment = Uri.parse(url.fragment);
final code = fragment.queryParameters[SpaceConstants.classCode];
if (code != null && fragment.path.contains('join_with_link')) {
await SpaceCodeRepo.setSpaceCode(code);
codeNotifier.value = code;
}
}
Future<void> cacheSpaceCode(String code) async {
if (code.isEmpty) return;
await _spaceStorage.write(
PLocalKey.cachedSpaceCodeToJoin,
code,
);
codeNotifier.value = code;
}
String? get justInputtedCode =>
_spaceStorage.read(PLocalKey.justInputtedCode);
String? get cachedSpaceCode =>
_spaceStorage.read(PLocalKey.cachedSpaceCodeToJoin);
Future<String?> joinCachedSpaceCode(BuildContext context) async {
final String? spaceCode = cachedSpaceCode;
static Future<String?> joinCachedSpaceCode(BuildContext context) async {
final String? spaceCode = SpaceCodeRepo.spaceCode;
if (spaceCode == null) return null;
final spaceId = await joinSpaceWithCode(
context,
spaceCode,
);
await _spaceStorage.remove(
PLocalKey.cachedSpaceCodeToJoin,
);
await SpaceCodeRepo.clearSpaceCode();
if (spaceId != null) {
final room = _pangeaController.matrixState.client.getRoomById(spaceId);
final room =
MatrixState.pangeaController.matrixState.client.getRoomById(spaceId);
room?.isSpace ?? true
? context.go('/rooms/spaces/$spaceId/details')
: context.go('/rooms/${room?.id}');
return spaceId;
}
return null;
}
Future<String?> joinSpaceWithCode(
static Future<String?> joinSpaceWithCode(
BuildContext context,
String spaceCode, {
String? notFoundError,
}) async {
final client = _pangeaController.matrixState.client;
await _spaceStorage.write(
PLocalKey.justInputtedCode,
spaceCode,
);
final client = MatrixState.pangeaController.matrixState.client;
await SpaceCodeRepo.setRecentCode(spaceCode);
final resp = await showFutureLoadingDialog<KnockSpaceResponse>(
context: context,
@ -148,8 +124,8 @@ class SpaceCodeController extends BaseController {
return roomIdToJoin;
}
Future<void> _joinSpace(String spaceId) async {
final client = _pangeaController.matrixState.client;
static Future<void> _joinSpace(String spaceId) async {
final client = MatrixState.pangeaController.matrixState.client;
await client.joinRoomById(spaceId);
Room? room = client.getRoomById(spaceId);
@ -180,14 +156,4 @@ class SpaceCodeController extends BaseController {
await room.requestParticipants();
}
}
static Future<void> onOpenAppViaUrl(Uri url) async {
if (url.fragment.isEmpty) return;
final fragment = Uri.parse(url.fragment);
final code = fragment.queryParameters[SpaceConstants.classCode];
if (code != null && fragment.path.contains('join_with_link')) {
await MatrixState.pangeaController.spaceCodeController
.cacheSpaceCode(code);
}
}
}

View file

@ -0,0 +1,36 @@
import 'package:get_storage/get_storage.dart';
import 'package:fluffychat/pangea/common/constants/local.key.dart';
class SpaceCodeRepo {
static final GetStorage _spaceStorage = GetStorage('class_storage');
static String? get spaceCode =>
_spaceStorage.read(PLocalKey.cachedSpaceCodeToJoin);
static String? get recentCode =>
_spaceStorage.read(PLocalKey.justInputtedCode);
static Future<void> setSpaceCode(String code) async {
if (code.isEmpty) return;
await _spaceStorage.write(
PLocalKey.cachedSpaceCodeToJoin,
code,
);
}
static Future<void> setRecentCode(String code) async {
await _spaceStorage.write(
PLocalKey.justInputtedCode,
code,
);
}
static Future<void> clearSpaceCode() async {
await _spaceStorage.remove(PLocalKey.cachedSpaceCodeToJoin);
}
static Future<void> clearRecentCode() async {
await _spaceStorage.remove(PLocalKey.justInputtedCode);
}
}

View file

@ -2,9 +2,6 @@ import 'package:fluffychat/config/app_config.dart';
class SpaceConstants {
static const powerLevelOfAdmin = 100;
static const languageToolPermissions = 1;
static const defaultDominantLanguage = "en";
static const defaultTargetLanguage = "es";
static const String classCode = 'classcode';
static const String introductionChatAlias = 'introductionChat';
static const String announcementsChatAlias = 'announcementsChat';

View file

@ -1,26 +0,0 @@
import 'dart:convert';
import 'package:matrix/matrix.dart';
class SpaceCodeUtil {
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) {
throw Exception('Failed to generate room code: $response');
}
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');
}
}
}

View file

@ -0,0 +1,34 @@
import 'dart:convert';
import 'package:http/http.dart' hide Client;
import 'package:matrix/matrix.dart';
import 'package:matrix/matrix_api_lite/generated/api.dart';
extension SpaceCodeExtension on Api {
Future<String> getSpaceCode() async {
final requestUri = Uri(
path: '/_synapse/client/pangea/v1/request_room_code',
);
final request = Request('GET', baseUri!.resolveUri(requestUri));
request.headers['content-type'] = 'application/json';
request.headers['authorization'] = 'Bearer ${bearerToken!}';
final response = await httpClient.send(request);
final responseBody = await response.stream.toBytes();
final responseString = utf8.decode(responseBody);
if (response.statusCode != 200) {
throw Exception(
'HTTP error response: statusCode=${response.statusCode}, body=$responseString',
);
}
final json = jsonDecode(responseString);
if (json['access_code'] is String) {
return json['access_code'] as String;
} else {
throw Exception('Invalid response, access_code not found $response');
}
}
}
extension SpaceCodeRequest on Client {
Future<String> requestSpaceCode() => getSpaceCode();
}

View file

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/pangea/spaces/space_code_controller.dart';
//if on home with classcode in url and not logged in, then save it soemhow and after llogin, join class automatically
//if on home with classcode in url and logged in, then join class automatically
@ -33,8 +33,7 @@ class _JoinClassWithLinkState extends State<JoinClassWithLink> {
}
if (widget.classCode != null) {
await MatrixState.pangeaController.spaceCodeController
.cacheSpaceCode(widget.classCode!);
await SpaceCodeController.cacheSpaceCode(widget.classCode!);
}
context.push("/home");
});

View file

@ -1,153 +0,0 @@
import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:fluffychat/config/themes.dart';
import 'package:fluffychat/pages/chat_list/status_msg_list.dart';
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
import 'package:fluffychat/pangea/spaces/utils/load_participants_util.dart';
import 'package:fluffychat/utils/stream_extension.dart';
import 'package:fluffychat/widgets/adaptive_dialogs/user_dialog.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:fluffychat/widgets/presence_builder.dart';
class LeaderboardParticipantList extends StatefulWidget {
final Room space;
const LeaderboardParticipantList({
required this.space,
super.key,
});
static const double height = 116;
@override
State<LeaderboardParticipantList> createState() =>
LeaderboardParticipantListState();
}
class LeaderboardParticipantListState
extends State<LeaderboardParticipantList> {
final _scrollController = ScrollController();
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final client = Matrix.of(context).client;
final theme = Theme.of(context);
return StreamBuilder(
stream: client.onSync.stream.rateLimit(const Duration(seconds: 3)),
builder: (context, snapshot) {
return LoadParticipantsBuilder(
room: widget.space,
loadProfiles: true,
builder: (context, participantsLoader) {
final participants = participantsLoader.sortedParticipants
.where((p) => p.membership == Membership.join)
.toList();
return AnimatedSize(
duration: FluffyThemes.animationDuration,
curve: Curves.easeInOut,
child: SizedBox(
height: 130.0,
child: Scrollbar(
controller: _scrollController,
child: ListView.builder(
controller: _scrollController,
padding: const EdgeInsets.fromLTRB(
8.0,
8.0,
8.0,
16.0,
),
scrollDirection: Axis.horizontal,
itemCount: participants.length,
itemBuilder: (context, i) {
final user = participants[i];
final publicProfile =
participantsLoader.getAnalyticsProfile(
user.id,
);
LinearGradient? gradient = i.leaderboardGradient;
if (user.id == BotName.byEnvironment ||
publicProfile == null ||
publicProfile.level == null) {
gradient = null;
}
return PresenceBuilder(
userId: user.id,
builder: (context, presence) {
Color? dotColor;
if (presence != null) {
dotColor = presence.presence.isOnline
? Colors.green
: presence.presence.isUnavailable
? Colors.orange
: Colors.grey;
}
return PresenceAvatar(
presence: presence ??
CachedPresence(
PresenceType.unavailable,
null,
null,
null,
user.id,
),
height: StatusMessageList.height,
onTap: (profile) => UserDialog.show(
context: context,
profile: profile,
),
gradient: gradient,
showPresence: false,
floatingIndicator: Positioned(
bottom: 0,
right: 0,
child: Container(
width: 16,
height: 16,
decoration: BoxDecoration(
color: theme.colorScheme.surface,
borderRadius: BorderRadius.circular(32),
),
alignment: Alignment.center,
child: Container(
width: 10,
height: 10,
decoration: BoxDecoration(
color: dotColor,
borderRadius: BorderRadius.circular(16),
border: Border.all(
width: 1,
color: theme.colorScheme.surface,
),
),
),
),
),
);
},
);
},
),
),
),
);
},
);
},
);
}
}

View file

@ -2,7 +2,7 @@ import 'package:matrix/matrix.dart';
import 'package:fluffychat/pangea/common/controllers/base_controller.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/learning_settings/enums/tool_settings_enum.dart';
class PermissionsController extends BaseController {
late PangeaController _pangeaController;

View file

@ -4,7 +4,7 @@ import 'package:fluffychat/pangea/common/constants/model_keys.dart';
import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/instructions/instruction_settings.dart';
import 'package:fluffychat/pangea/learning_settings/enums/language_level_type_enum.dart';
import 'package:fluffychat/pangea/spaces/models/space_model.dart';
import 'package:fluffychat/pangea/learning_settings/enums/tool_settings_enum.dart';
import 'package:fluffychat/widgets/matrix.dart';
import '../../learning_settings/models/language_model.dart';

View file

@ -24,7 +24,7 @@ import 'package:fluffychat/pangea/common/controllers/pangea_controller.dart';
import 'package:fluffychat/pangea/common/utils/any_state_holder.dart';
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
import 'package:fluffychat/pangea/learning_settings/utils/locale_provider.dart';
import 'package:fluffychat/pangea/spaces/controllers/space_code_controller.dart';
import 'package:fluffychat/pangea/spaces/space_code_controller.dart';
import 'package:fluffychat/utils/client_manager.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart';
import 'package:fluffychat/utils/platform_infos.dart';