generated from ttipo/project-base
cdd4856300
기기 저장소를 API 로 바꾸기 전에, 모든 도메인이 함께 쓸 네트워크 계층을 먼저 갖춘다. - DATA_MODE(api|local): 기본은 서버. .env 를 읽지 않는 테스트·화면 확인은 기기 저장소로 돈다 - SessionStore: 액세스·리프레시 토큰을 secure storage 에 두고 앱을 열 때 미리 읽는다 (모바일에는 쿠키 저장소가 없어 리프레시 토큰도 secure storage 에 둔다) - DioClient: 401 이면 토큰을 한 번 갱신해 다시 보낸다(동시 요청도 갱신은 한 번). 서버가 갱신을 거절하면 세션을 끊고 AUTH_002, 서버에 닿지 못하면 세션은 두고 SYS_001 - 실패 알림은 사전 문구로 토스트 한 곳에서 띄우고 같은 코드는 잠깐 한 번만 — 호출부가 처리하는 코드는 끌 수 있다 - 사진: 경로 자리에 server-file:<id> 를 담고, 기기 사진은 저장할 때 형식을 내용으로 확인해 올린다. 서버 사진은 Dio 로 받아 토큰 갱신을 그대로 쓴다 (PetPhotoImage·PersonAvatar) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
1.6 KiB
Dart
44 lines
1.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:tma_app/app.dart';
|
|
import 'package:tma_app/core/api/dio_provider.dart';
|
|
import 'package:tma_app/core/api/session_store.dart';
|
|
import 'package:tma_app/core/config/app_config.dart';
|
|
import 'package:tma_app/core/storage/preferences_provider.dart';
|
|
import 'package:tma_app/shared/widgets/rup_toast.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
// dotenv 로드 — .env 파일이 없으면 기본값으로 동작
|
|
try {
|
|
await dotenv.load(fileName: '.env');
|
|
} catch (_) {
|
|
// .env 파일이 없는 경우 무시 (기본값 사용)
|
|
}
|
|
|
|
// 시안은 세로 화면 전용이다
|
|
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
|
|
|
|
// 진입 화면 결정에 필요한 저장값을 첫 프레임 전에 읽어 둔다
|
|
final prefs = await SharedPreferences.getInstance();
|
|
// 로그인 세션(토큰) — 서버 모드에서만 secure storage 를 쓴다
|
|
final session = readDataMode() == DataMode.api
|
|
? await SessionStore.load(const SecureTokenVault())
|
|
: SessionStore(MemoryTokenVault());
|
|
|
|
runApp(
|
|
ProviderScope(
|
|
overrides: [
|
|
sharedPreferencesProvider.overrideWithValue(prefs),
|
|
sessionStoreProvider.overrideWithValue(session),
|
|
apiErrorReporterProvider.overrideWith(apiErrorToastReporter),
|
|
],
|
|
child: const RupApp(),
|
|
),
|
|
);
|
|
}
|