import 'package:app/global/config.dart'; import 'package:app/request/api/room_api.dart'; import 'package:app/request/dto/room/board_token_dto.dart'; import 'package:flutter/material.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'board_dialog.dart'; class BoardManager { BoardManager._(); static final BoardManager _instance = BoardManager._(); factory BoardManager() => _instance; WebViewController? _webViewController; BoardTokenDto? _boardToken; ///获取token Future _fetchToken(int roomId) async { final now = DateTime.now(); if (_boardToken == null) { EasyLoading.show(status: "开启白板中"); _boardToken = await getBoardTokenApi(roomId); } else { //离过期差多少小时 int remainSeconds = _boardToken!.expiresAt.difference(now).inSeconds; // 剩余不足 2 小时 = 7200 秒 if (remainSeconds <= 7200) { EasyLoading.show(status: "开启白板中"); _boardToken = await getBoardTokenApi(roomId); } } EasyLoading.dismiss(); } ///生成完整 URL /// -[uid] 用户 /// -[roomId] 房间id /// -[isTeacher] 是否是老师 Future buildUrl({ required String uid, required int roomId, required bool isTeacher, }) async { await _fetchToken(roomId); Map params = { "appid": _boardToken!.whiteboardAppid, "uid": uid, "uuid": _boardToken!.whiteboardUuid, "room_token": _boardToken!.whiteboardToken, "write": isTeacher ? 1 : 0, }; String paramStr = params.entries.map((e) => "${e.key}=${e.value}").join("&"); return "${Config.webUrl}/board?$paramStr"; } /// 获取全局唯一 WebViewController Future getController(String url) async { if (_webViewController != null) return _webViewController!; _webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setNavigationDelegate( // ⭐ 加上加载监听(BoardDialog 再 listen 一次也没关系) NavigationDelegate( onPageStarted: (_) {}, onPageFinished: (_) {}, ), ) ..loadRequest(Uri.parse(url)); return _webViewController!; } ///打开白板 /// -[uid] 用户名+id /// -[roomId] 房间id /// -[isTeacher] 是否是老师 Future showBoardDialog( BuildContext context, { required String uid, required int roomId, required bool isTeacher, }) async { String url = await buildUrl( uid: uid, roomId: roomId, isTeacher: isTeacher, ); final controller = await getController(url); showDialog( context: context, builder: (_) => BoardDialog(controller: controller), ); } }