Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 31 additions & 4 deletions lib/ui/camera/services/scan_data_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class ScanDataService {

/// 取得したTIDに基づいて、アニメ詳細情報を取得する
static Future<List<Map<String, dynamic>>> getAnimeDetails(
Set<String> tids) async {
Set<String> tids,
) async {
List<Map<String, dynamic>> animeList = [];
try {
// "titles" コレクションから全件取得(件数が多い場合は where クエリなどで絞ることを検討)
Expand Down Expand Up @@ -103,8 +104,9 @@ class ScanDataService {

// URLフォーマットの場合: https://animeishi-viewer.web.app/user/USER_ID
if (trimmedValue.startsWith('https://animeishi-viewer.web.app/user/')) {
final userId = trimmedValue
.substring('https://animeishi-viewer.web.app/user/'.length);
final userId = trimmedValue.substring(
'https://animeishi-viewer.web.app/user/'.length,
);
return userId.isNotEmpty ? userId : null;
}

Expand All @@ -130,7 +132,9 @@ class ScanDataService {

/// analysisCommentを取得
static Future<String?> getAnalysisComment(
String currentUserId, String friendUserId) async {
String currentUserId,
String friendUserId,
) async {
try {
final doc = await _firestore
.collection('users')
Expand All @@ -146,6 +150,29 @@ class ScanDataService {
}
return null;
}

/// analysisCommentを保存
static Future<void> saveAnalysisComment(
String currentUserId,
String friendUserId,
String comment,
) async {
try {
await _firestore
.collection('users')
.doc(currentUserId)
.collection('meishies')
.doc(friendUserId)
.set({
'analysisComment': comment,
'updatedAt': FieldValue.serverTimestamp(),
}, SetOptions(merge: true));
print('analysisComment保存成功');
} catch (e) {
print('analysisComment保存エラー: $e');
rethrow;
}
}
}

/// スキャンデータ取得結果を格納するクラス
Expand Down
92 changes: 66 additions & 26 deletions lib/ui/camera/view/scandata.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:animeishi/ui/home/view/home_page.dart';
import 'package:animeishi/ui/camera/services/anime_analysis_service.dart';
import 'package:animeishi/ui/camera/services/scan_data_service.dart';
import '../controllers/scan_result_animation_controller.dart';
import '../services/scan_data_service.dart';
import '../components/scan_result_widgets.dart';
import '../components/scan_result_painters.dart';

Expand Down Expand Up @@ -60,6 +60,23 @@ class _ScanDataWidgetState extends State<ScanDataWidget>
// データ取得
try {
final result = await ScanDataService.fetchUserData(_userId!);

// 既存の分析結果を取得
final currentUserId = FirebaseAuth.instance.currentUser?.uid;
if (currentUserId != null && result.success) {
final savedComment = await ScanDataService.getAnalysisComment(
currentUserId,
_userId!,
);
if (savedComment != null) {
if (!mounted) return;
setState(() {
analysisComment = savedComment;
});
}
}

if (!mounted) return;
setState(() {
_scanResult = result;
_isLoading = false;
Expand Down Expand Up @@ -94,11 +111,28 @@ class _ScanDataWidgetState extends State<ScanDataWidget>
animeList,
username: username,
);

// 分析結果をFirestoreに保存
final currentUserId = FirebaseAuth.instance.currentUser?.uid;
if (currentUserId != null) {
try {
await ScanDataService.saveAnalysisComment(
currentUserId,
userId,
comment,
);
} catch (e) {
debugPrint('analysisComment保存失敗: $e');
}
}

if (!mounted) return;
setState(() {
analysisComment = comment;
isAnalyzing = false;
});
} catch (e) {
if (!mounted) return;
setState(() {
analysisComment = 'AI分析に失敗しました: $e';
isAnalyzing = false;
Expand Down Expand Up @@ -166,10 +200,7 @@ class _ScanDataWidgetState extends State<ScanDataWidget>
(route) => false,
);
},
icon: const Icon(
Icons.arrow_back,
color: Color(0xFF667EEA),
),
icon: const Icon(Icons.arrow_back, color: Color(0xFF667EEA)),
),
),
),
Expand Down Expand Up @@ -225,30 +256,13 @@ class _ScanDataWidgetState extends State<ScanDataWidget>
ScanResultWidgets.buildAnimeListCard(animeList),

const SizedBox(height: 24),
ElevatedButton.icon(
icon: const Icon(Icons.insights),
label: const Text('AIで視聴傾向を分析'),
onPressed: isAnalyzing ? null : () => _runAnalysis(_userId!),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF667EEA),
foregroundColor: Colors.white,
minimumSize: const Size(double.infinity, 48),
),
),
const SizedBox(height: 16),
if (isAnalyzing)
Row(
children: [
const CircularProgressIndicator(),
const SizedBox(width: 12),
const Text('分析中...'),
],
),
if (analysisComment != null)

// 分析結果表示(既存の場合)
if (analysisComment != null && !isAnalyzing)
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.only(top: 8),
margin: const EdgeInsets.only(bottom: 16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
Expand Down Expand Up @@ -282,6 +296,32 @@ class _ScanDataWidgetState extends State<ScanDataWidget>
],
),
),

// 分析ボタン
ElevatedButton.icon(
icon: const Icon(Icons.insights),
label: Text(analysisComment != null ? 'AIで再分析' : 'AIで視聴傾向を分析'),
onPressed: isAnalyzing ? null : () => _runAnalysis(_userId!),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF667EEA),
foregroundColor: Colors.white,
minimumSize: const Size(double.infinity, 48),
),
),

// 分析中表示
if (isAnalyzing)
const Padding(
padding: EdgeInsets.only(top: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(width: 12),
Text('分析中...'),
],
),
),
],
),
),
Expand Down