Skip to content
Open
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
8 changes: 4 additions & 4 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
Expand All @@ -24,6 +26,8 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand All @@ -41,9 +45,5 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
13 changes: 2 additions & 11 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import 'screens/manga_reader_screen.dart';
import 'pages/manga_reader/manga_reader_page.dart';

void main() {
runApp(const ProviderScope(child: MyApp()));
Expand Down Expand Up @@ -187,19 +187,10 @@ class ScreenD extends StatelessWidget {
const SizedBox(height: 30),
ElevatedButton(
onPressed: () {
// 仮の漫画データを直接作成
final List<String> dummyPages = [
'Page 1',
'Page 2',
'Page 3',
'Page 4',
'Page 5',
];

Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MangaReaderScreen(pages: dummyPages),
builder: (context) => const MangaReaderPage(),
),
);
},
Expand Down
150 changes: 150 additions & 0 deletions lib/pages/manga_reader/manga_reader_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../providers/providers.dart';
import 'widgets/manga_page_widget.dart';
import 'widgets/manga_reader_controls.dart';

class MangaReaderPage extends ConsumerStatefulWidget {
const MangaReaderPage({super.key});

@override
ConsumerState<MangaReaderPage> createState() => _MangaReaderPageState();
}

class _MangaReaderPageState extends ConsumerState<MangaReaderPage> {
late PageController _pageController;

@override
void initState() {
super.initState();
_pageController = PageController();

// 初期化時にサンプルページを設定
WidgetsBinding.instance.addPostFrameCallback((_) {
final notifier = ref.read(mangaReaderNotifierProvider.notifier);
notifier.setPages([
'Page 1',
'Page 2',
'Page 3',
'Page 4',
'Page 5',
]);
});
}

@override
void dispose() {
_pageController.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
final readerState = ref.watch(mangaReaderNotifierProvider);
final notifier = ref.read(mangaReaderNotifierProvider.notifier);

return Scaffold(
backgroundColor: Colors.black,
appBar: readerState.isControlsVisible
? AppBar(
backgroundColor: Colors.black,
foregroundColor: Colors.white,
title: const Text('漫画ビューワー'),
actions: [
IconButton(
icon: const Icon(Icons.settings),
onPressed: () => _showSettings(context),
),
],
)
: null,
body: readerState.pages.isEmpty
? const Center(
child: CircularProgressIndicator(
color: Colors.white,
),
)
: Stack(
children: [
// メインの漫画ページ
GestureDetector(
onTap: () => notifier.toggleControlsVisibility(),
child: PageView.builder(
controller: _pageController,
itemCount: readerState.pages.length,
onPageChanged: (index) {
notifier.goToPage(index);
},
itemBuilder: (context, index) {
return MangaPageWidget(
pageContent: readerState.pages[index],
scale: readerState.scale,
);
},
),
),
// コントロール
if (readerState.isControlsVisible)
MangaReaderControls(
currentPage: readerState.currentPage,
totalPages: readerState.pages.length,
onPreviousPage: () {
notifier.previousPage();
_pageController.previousPage(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
onNextPage: () {
notifier.nextPage();
_pageController.nextPage(
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
},
),
],
),
);
}

void _showSettings(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('設定'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: const Icon(Icons.brightness_6),
title: const Text('明るさ調整'),
onTap: () {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('明るさ調整機能は未実装です')),
);
},
),
ListTile(
leading: const Icon(Icons.zoom_in),
title: const Text('表示設定'),
onTap: () {
Navigator.pop(context);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('表示設定機能は未実装です')),
);
},
),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('閉じる'),
),
],
),
);
}
}
37 changes: 37 additions & 0 deletions lib/pages/manga_reader/notifier/manga_reader_notifier.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../state/manga_reader_state.dart';

class MangaReaderNotifier extends Notifier<MangaReaderState> {
@override
MangaReaderState build() => const MangaReaderState();

void setPages(List<String> pages) {
state = state.copyWith(pages: pages);
}

void nextPage() {
if (state.currentPage < state.pages.length - 1) {
state = state.copyWith(currentPage: state.currentPage + 1);
}
}

void previousPage() {
if (state.currentPage > 0) {
state = state.copyWith(currentPage: state.currentPage - 1);
}
}

void goToPage(int page) {
if (page >= 0 && page < state.pages.length) {
state = state.copyWith(currentPage: page);
}
}

void setScale(double scale) {
state = state.copyWith(scale: scale.clamp(0.5, 3.0));
}

void toggleControlsVisibility() {
state = state.copyWith(isControlsVisible: !state.isControlsVisible);
}
}
13 changes: 13 additions & 0 deletions lib/pages/manga_reader/state/manga_reader_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'manga_reader_state.freezed.dart';

@freezed
class MangaReaderState with _$MangaReaderState {
const factory MangaReaderState({
@Default(0) int currentPage,
@Default(1.0) double scale,
@Default(true) bool isControlsVisible,
@Default([]) List<String> pages,
}) = _MangaReaderState;
}
Loading