feat: 알림 재예약 개선과 패키지 업그레이드

This commit is contained in:
JiWoong Sul
2025-09-19 18:10:47 +09:00
parent e909ba59a4
commit 87f82546a4
24 changed files with 210 additions and 122 deletions

View File

@@ -9,7 +9,7 @@ import '../widgets/add_subscription/add_subscription_save_button.dart';
/// 새로운 구독을 추가하는 화면
class AddSubscriptionScreen extends StatefulWidget {
const AddSubscriptionScreen({Key? key}) : super(key: key);
const AddSubscriptionScreen({super.key});
@override
State<AddSubscriptionScreen> createState() => _AddSubscriptionScreenState();

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode;
import 'package:provider/provider.dart';
import '../providers/notification_provider.dart';
import 'dart:io';
@@ -694,6 +694,25 @@ class SettingsScreen extends StatelessWidget {
),
),
),
if (kDebugMode)
Padding(
padding:
const EdgeInsets.only(
top: 16.0),
child: SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
icon: const Icon(Icons
.notifications_active),
label:
const Text('테스트 알림'),
onPressed: () {
NotificationService
.showTestPaymentNotification();
},
),
),
),
],
),
),

View File

@@ -16,18 +16,21 @@ class SmsScanScreen extends StatefulWidget {
class _SmsScanScreenState extends State<SmsScanScreen> {
late SmsScanController _controller;
late final ScrollController _scrollController;
@override
void initState() {
super.initState();
_controller = SmsScanController();
_controller.addListener(_handleControllerUpdate);
_scrollController = ScrollController();
}
@override
void dispose() {
_controller.removeListener(_handleControllerUpdate);
_controller.dispose();
_scrollController.dispose();
super.dispose();
}
@@ -93,16 +96,37 @@ class _SmsScanScreenState extends State<SmsScanScreen> {
websiteUrlController: _controller.websiteUrlController,
selectedCategoryId: _controller.selectedCategoryId,
onCategoryChanged: _controller.setSelectedCategoryId,
onAdd: () => _controller.addCurrentSubscription(context),
onSkip: () => _controller.skipCurrentSubscription(context),
onAdd: _handleAddSubscription,
onSkip: _handleSkipSubscription,
),
],
);
}
Future<void> _handleAddSubscription() async {
await _controller.addCurrentSubscription(context);
if (!mounted) return;
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToTop());
}
void _handleSkipSubscription() {
_controller.skipCurrentSubscription(context);
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToTop());
}
void _scrollToTop() {
if (!_scrollController.hasClients) return;
_scrollController.animateTo(
0,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
controller: _scrollController,
padding: EdgeInsets.zero,
child: Column(
children: [

View File

@@ -186,7 +186,7 @@ class _SplashScreenState extends State<SplashScreen>
),
),
);
}).toList(),
}),
// 상단 원형 장식 제거(단색 배경 유지)
Positioned(