Files
school-attendance/lib/main_client_app.dart
T
sihooandClaude Sonnet 5 2d87a681ca 스크롤 시 나오는 파란 오버스크롤 글로우 효과 제거
Flutter 기본 GlowingOverscrollIndicator가 스크롤 경계에서 파란색으로
번쩍이던 걸 커스텀 ScrollBehavior로 전체 앱에서 비활성화.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-08 18:05:18 +09:00

115 lines
3.4 KiB
Dart

// 🚪 앱 진입점. Firebase/백그라운드 감시 서비스 초기화 후 로그인 화면으로 시작한다.
// 실제 화면 구현은 lib/screens/ 폴더, 공통 설정은 lib/config.dart 참고.
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'config.dart';
import 'function/session_store.dart';
import 'pocket_watch_service.dart';
import 'theme/app_palette.dart';
import 'ui/login_screen.dart';
import 'ui/main_dashboard.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await printFCMToken();
if (!kIsWeb && Platform.isAndroid) {
await initializePocketWatchService();
}
runApp(const SchoolAttendanceApp());
}
// 🌊 스크롤이 끝에 닿을 때 나오는 파란색 오버스크롤 글로우 효과를 없앤다.
class _NoGlowScrollBehavior extends MaterialScrollBehavior {
@override
Widget buildOverscrollIndicator(
BuildContext context,
Widget child,
ScrollableDetails details,
) {
return child;
}
}
class SchoolAttendanceApp extends StatelessWidget {
const SchoolAttendanceApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: '$schoolName 학생 도우미',
scrollBehavior: _NoGlowScrollBehavior(),
theme: ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: AppPalette.mist,
colorScheme:
ColorScheme.fromSeed(
seedColor: AppPalette.ink,
brightness: Brightness.light,
).copyWith(
primary: AppPalette.ink,
onPrimary: AppPalette.paper,
secondary: AppPalette.ink,
onSecondary: AppPalette.paper,
surface: AppPalette.paper,
onSurface: AppPalette.ink,
),
),
home: const _StartupGate(), // 🚪 저장된 로그인이 있으면 대시보드로, 없으면 로그인 화면으로.
);
}
}
/// 🔐 "로그인 유지" 진입점. 기기에 저장된 세션이 있는지 확인하는 동안 잠깐 로딩을 보여주고,
/// 있으면 로그인 화면 없이 바로 대시보드로, 없으면 로그인 화면으로 보낸다.
class _StartupGate extends StatefulWidget {
const _StartupGate();
@override
State<_StartupGate> createState() => _StartupGateState();
}
class _StartupGateState extends State<_StartupGate> {
SavedSession? _session;
bool _checked = false;
@override
void initState() {
super.initState();
_checkSession();
}
Future<void> _checkSession() async {
final session = await SessionStore.load();
if (!mounted) return;
setState(() {
_session = session;
_checked = true;
});
}
@override
Widget build(BuildContext context) {
if (!_checked) {
return Scaffold(
backgroundColor: AppPalette.mist,
body: const Center(child: CircularProgressIndicator()),
);
}
final session = _session;
if (session != null) {
return MainDashboard(
userId: session.userId,
userName: session.userName,
role: session.role,
isDeviceMatched: session.isDeviceMatched,
);
}
return const LoginScreen();
}
}