diff --git a/lib/function/profile_shop_controller.dart b/lib/function/profile_shop_controller.dart index c4114e7..3eda413 100644 --- a/lib/function/profile_shop_controller.dart +++ b/lib/function/profile_shop_controller.dart @@ -9,6 +9,7 @@ import '../theme/profile_themes.dart'; class ShopTemplate { final int id; + final String code; final String category; final String name; final int price; @@ -19,6 +20,7 @@ class ShopTemplate { ShopTemplate({ required this.id, + required this.code, required this.category, required this.name, required this.price, @@ -31,6 +33,7 @@ class ShopTemplate { factory ShopTemplate.fromJson(Map json) { return ShopTemplate( id: json['id'] as int, + code: json['code'] as String, category: json['category'] as String, name: json['name'] as String, price: json['price'] as int, diff --git a/lib/ui/profile_customize_screen.dart b/lib/ui/profile_customize_screen.dart index 92ca4bd..e43de89 100644 --- a/lib/ui/profile_customize_screen.dart +++ b/lib/ui/profile_customize_screen.dart @@ -32,15 +32,10 @@ class _ProfileCustomizeScreenState extends State { // null = 아직 직접 고르지 않음(장착된 테마를 그대로 보여줌), -1 = "기본 모습"을 명시적으로 미리보는 중. int? _previewTemplateId; - // 🎨 지금 실제로 장착 중인 테마 - 화면 배경/상점 타일 자체를 이걸로 물들인다. - // (미리보기는 큰 타일 하나만 바뀌는 것과 별개로, 이건 "진짜 내 테마"를 화면 전체에 반영) - ProfileTheme? _equippedTheme; - @override void initState() { super.initState(); _controller.loadCatalog(widget.studentId); - _loadEquippedTheme(); } @override @@ -49,16 +44,8 @@ class _ProfileCustomizeScreenState extends State { super.dispose(); } - Future _loadEquippedTheme() async { - final theme = await ProfileShopController.fetchEquippedTheme( - widget.studentId, - ); - if (!mounted) return; - setState(() => _equippedTheme = theme); - } - - /// 지금 큰 타일에 보여줄 테마를 고른다. 직접 미리보기를 누른 게 있으면 그걸, - /// 없으면 실제 장착 중인 테마를, 그마저도 없으면 null(기본 모습)을 돌려준다. + /// 지금 큰 타일에 보여줄 템플릿을 고른다. 직접 미리보기를 누른 게 있으면 그걸, + /// 없으면 실제 장착 중인 템플릿을, 그마저도 없으면 null(기본 모습)을 돌려준다. ShopTemplate? _resolvePreviewTemplate() { if (_previewTemplateId == -1) return null; if (_previewTemplateId != null) { @@ -72,6 +59,15 @@ class _ProfileCustomizeScreenState extends State { return null; } + /// 🎨 지금 "체험하기/미리보기" 중인 테마로 화면 전체(배경/타일/버튼)를 물들인다. + /// 아무것도 직접 고르지 않았으면 실제 장착된 테마가 그대로 나오고, "기본 모습"을 + /// 고르면 null이 되어 화면이 원래 모습으로 돌아간다 - 체험하기를 누르면 바로 + /// 커스텀 화면 전체에 반영되는 효과를 _resolvePreviewTemplate() 하나로 처리한다. + ProfileTheme? get _displayTheme { + final preview = _resolvePreviewTemplate(); + return preview == null ? null : profileThemes[preview.code]; + } + Future _handlePurchase(ShopTemplate template) async { setState(() => _previewTemplateId = template.id); final (success, message) = await _controller.purchase( @@ -92,7 +88,6 @@ class _ProfileCustomizeScreenState extends State { widget.studentId, templateId, ); - if (success) await _loadEquippedTheme(); if (!mounted) return; AppNotice.show( context, @@ -104,7 +99,7 @@ class _ProfileCustomizeScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - backgroundColor: _equippedTheme?.background ?? AppPalette.mist, + backgroundColor: _displayTheme?.background ?? AppPalette.mist, appBar: AppBar( backgroundColor: Colors.transparent, foregroundColor: AppPalette.ink, @@ -148,7 +143,7 @@ class _ProfileCustomizeScreenState extends State { return Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 14), decoration: BoxDecoration( - color: _equippedTheme?.secondary ?? AppPalette.ink, + color: _displayTheme?.secondary ?? AppPalette.ink, borderRadius: BorderRadius.circular(18), ), child: Row( @@ -246,7 +241,7 @@ class _ProfileCustomizeScreenState extends State { _DefaultTemplateTile( equipped: !hasEquippedTemplate, previewing: previewId == null, - theme: _equippedTheme, + theme: _displayTheme, onEquip: () => _handleEquip(null), onPreview: () => setState(() => _previewTemplateId = -1), ), @@ -255,7 +250,7 @@ class _ProfileCustomizeScreenState extends State { template: template, canAfford: _controller.cashBalance >= template.price, previewing: previewId == template.id, - theme: _equippedTheme, + theme: _displayTheme, onPurchase: () => _handlePurchase(template), onEquip: () => _handleEquip(template.id), onPreview: () => setState(() => _previewTemplateId = template.id),