web_page.dart 6.83 KB
import 'dart:io';

import 'package:appframe/bloc/web_cubit.dart';
import 'package:appframe/config/env_config.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebPage extends StatelessWidget {
  const WebPage({super.key});

  @override
  Widget build(BuildContext buildContext) {
    final Map<String, dynamic>? extraData = GoRouterState.of(buildContext).extra as Map<String, dynamic>?;

    var loginOpFlag = true;

    var sessionCode = extraData?['sessionCode'];
    var userCode = extraData?['userCode'];
    var classCode = extraData?['classCode'];
    var userType = extraData?['userType'];
    var stuId = extraData?['stuId'];

    if (sessionCode == null || sessionCode == '') {
      loginOpFlag = false;

      var sharedPreferences = getIt.get<SharedPreferences>();
      sessionCode = sharedPreferences.getString('auth_sessionCode');
      userCode = sharedPreferences.getString('auth_userCode');
      classCode = sharedPreferences.getString('auth_classCode');
      userType = sharedPreferences.getInt('auth_userType');
      stuId = sharedPreferences.getString('auth_stuId');
    }

    return BlocProvider(
      create: (context) {
        final webCubit = WebCubit(
          WebState(
            loginOpFlag: loginOpFlag,
            sessionCode: sessionCode,
            userCode: userCode,
            classCode: classCode,
            userType: userType,
            stuId: stuId,
          ),
        );
        return webCubit;
      },
      child: BlocConsumer<WebCubit, WebState>(
        builder: (ctx, state) {
          final scaffold = Scaffold(
            appBar: _buildAppBar(ctx, state),
            body: Stack(
              children: [
                state.loaded
                    ? SizedBox(
                        height: MediaQuery.of(ctx).size.height - 60, // 减去100像素留空
                        child: WebViewWidget(controller: ctx.read<WebCubit>().controller),
                      )
                    : const Center(
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: [
                            CircularProgressIndicator(color: Color(0xFF7691fa)),
                            SizedBox(height: 16),
                            Text('加载中...'),
                          ],
                        ),
                      ),
                // 添加升级遮罩层
                if (state.isUpgrading)
                  Container(
                    color: Colors.black54,
                    child: const Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          CircularProgressIndicator(color: Color(0xFF7691fa)),
                          SizedBox(height: 16),
                          Text('资源更新中...', style: TextStyle(color: Colors.white)),
                        ],
                      ),
                    ),
                  ),
              ],
            ),
            bottomNavigationBar: state.showBottomNavBar
                ? BottomNavigationBar(
                    type: BottomNavigationBarType.fixed,
                    currentIndex: state.selectedIndex,
                    selectedItemColor: Color(0xFF7691fa),
                    unselectedItemColor: Color(0xFF969799),
                    onTap: (index) {
                      // 更新选中索引
                      ctx.read<WebCubit>().updateSelectedIndex(index);
                      // 根据 index 执行相应的操作
                    },
                    items: const [
                      BottomNavigationBarItem(
                        icon: Icon(Icons.home, size: 32),
                        label: '我的班级',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.contact_page, size: 32),
                        label: '通讯录',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.find_in_page, size: 32),
                        label: '发现',
                      ),
                      BottomNavigationBarItem(
                        icon: Icon(Icons.person, size: 32),
                        label: '我的',
                      ),
                    ],
                  )
                : null,
          );

          // ios 不使用 PopScope
          if (Platform.isIOS) {
            return scaffold;
          }

          return PopScope(
            canPop: false,
            onPopInvokedWithResult: (didPop, result) {
              if (didPop) {
                return;
              }
              ctx.read<WebCubit>().handleBack();
            },
            child: scaffold,
          );
        },
        listener: (context, state) {
          if (state.suggestUpgrade) {
            context.read<WebCubit>().suggestUpgrade(context);
          } else if (state.orientationCmdFlag) {
            context.read<WebCubit>().getOrientation(context);
          } else if (state.windowInfoCmdFlag) {
            context.read<WebCubit>().getWindowInfo(context);
          } else if (state.chooseImageCmdFlag) {
            context.read<WebCubit>().chooseImage(context);
          } else if (state.chooseVideoCmdFlag) {
            context.read<WebCubit>().chooseVideo(context);
          }
        },
      ),
    );
  }

  AppBar _buildAppBar(BuildContext ctx, WebState state) {
    return AppBar(
      title: EnvConfig.isDev()
          ? Text(state.title + state.testMsg, style: TextStyle(color: Color(state.titleColor), fontSize: 18))
          : Text(state.title, style: TextStyle(color: Color(state.titleColor), fontSize: 18)),
      centerTitle: true,
      automaticallyImplyLeading: false,
      backgroundColor: Color(state.bgColor),
      actionsIconTheme: IconThemeData(color: Colors.white),
      leading: state.opIcon == 'back'
          ? IconButton(
              icon: const Icon(Icons.arrow_back, color: Colors.white),
              onPressed: () {
                ctx.read<WebCubit>().handleBack();
              },
            )
          : (state.opIcon == 'home'
              ? IconButton(
                  icon: const Icon(Icons.home, color: Colors.white),
                  onPressed: () {
                    ctx.read<WebCubit>().handleHome();
                  },
                )
              : null),
      actions: [
        IconButton(
          icon: const Icon(Icons.settings),
          onPressed: () {
            router.push('/setting');
          },
        ),
      ],
    );
  }
}