Skip to content

Commit dfba2e6

Browse files
committed
Added showing a page overlay while reading a comic [#149]
1 parent 0a819d0 commit dfba2e6

6 files changed

Lines changed: 319 additions & 210 deletions

File tree

androidVariant/src/main/java/org/comixedproject/variant/android/view/reading/ReadingPageView.kt renamed to androidVariant/src/main/java/org/comixedproject/variant/android/view/reading/PageNavigationView.kt

Lines changed: 101 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@ package org.comixedproject.variant.android.view.reading
2020

2121
import android.graphics.BitmapFactory
2222
import androidx.compose.foundation.Image
23+
import androidx.compose.foundation.clickable
24+
import androidx.compose.foundation.layout.Column
2325
import androidx.compose.foundation.layout.Row
2426
import androidx.compose.foundation.layout.fillMaxHeight
2527
import androidx.compose.foundation.layout.fillMaxSize
2628
import androidx.compose.foundation.layout.fillMaxWidth
27-
import androidx.compose.foundation.layout.padding
28-
import androidx.compose.material3.BottomAppBar
29+
import androidx.compose.foundation.rememberScrollState
30+
import androidx.compose.foundation.verticalScroll
2931
import androidx.compose.material3.Icon
3032
import androidx.compose.material3.IconButton
3133
import androidx.compose.material3.MaterialTheme
32-
import androidx.compose.material3.Scaffold
3334
import androidx.compose.material3.Slider
3435
import androidx.compose.material3.Text
3536
import androidx.compose.runtime.Composable
@@ -43,6 +44,7 @@ import androidx.compose.ui.Modifier
4344
import androidx.compose.ui.graphics.asImageBitmap
4445
import androidx.compose.ui.res.painterResource
4546
import androidx.compose.ui.res.stringResource
47+
import androidx.compose.ui.text.style.TextAlign
4648
import androidx.compose.ui.text.style.TextOverflow
4749
import androidx.compose.ui.tooling.preview.Preview
4850
import org.comixedproject.variant.adaptor.ArchiveAPI
@@ -51,42 +53,33 @@ import org.comixedproject.variant.android.R
5153
import org.comixedproject.variant.android.VariantTheme
5254
import org.comixedproject.variant.platform.Log
5355

54-
private const val TAG = "ReadingPageView"
56+
private const val TAG = "PageNavigationView"
5557

5658
@Composable
57-
fun ReadingPageView(
59+
fun PageNavigationView(
5860
comicFilename: String,
61+
comicTitle: String,
5962
pageFilename: String,
6063
title: String,
6164
currentPage: Int,
6265
totalPages: Int,
66+
showPageOverlay: Boolean,
6367
onChangePage: (Int) -> Unit,
6468
onStopReading: () -> Unit,
69+
onToggleShowOverlay: () -> Unit,
6570
modifier: Modifier = Modifier
6671
) {
6772
var currentPageContent by remember { mutableStateOf<ByteArray?>(null) }
6873

69-
Scaffold(
70-
content = { padding ->
71-
if (currentPageContent == null) {
72-
LaunchedEffect(currentPageContent) {
73-
currentPageContent =
74-
ArchiveAPI.loadPage(comicFilename, pageFilename)
75-
}
76-
} else {
77-
currentPageContent?.let { content ->
78-
Image(
79-
bitmap = BitmapFactory.decodeByteArray(content, 0, content.size)
80-
.asImageBitmap(),
81-
contentDescription = title,
82-
modifier = Modifier
83-
.padding(padding)
84-
.fillMaxHeight()
85-
)
86-
}
74+
Column(
75+
modifier = modifier
76+
.verticalScroll(rememberScrollState())
77+
.clickable {
78+
Log.debug(TAG, "Page tapped")
79+
onToggleShowOverlay()
8780
}
88-
},
89-
topBar = {
81+
.fillMaxSize()) {
82+
if (showPageOverlay) {
9083
Row(
9184
verticalAlignment = Alignment.CenterVertically,
9285
modifier = Modifier.fillMaxWidth()
@@ -107,69 +100,113 @@ fun ReadingPageView(
107100
}
108101

109102
Text(
110-
title,
103+
text = comicTitle,
111104
style = MaterialTheme.typography.titleMedium,
105+
textAlign = TextAlign.Center,
112106
maxLines = 1,
113107
overflow = TextOverflow.Ellipsis,
114108
modifier = Modifier.fillMaxWidth()
115109
)
116110
}
117-
},
118-
bottomBar = {
119-
BottomAppBar {
120-
Row(modifier = Modifier.fillMaxWidth()) {
121-
IconButton(onClick = {
122-
currentPageContent = null
123-
onChangePage(currentPage - 1)
124-
}, enabled = (currentPage > 0)) {
125-
Icon(
126-
painterResource(R.drawable.ic_previous_page),
127-
contentDescription = stringResource(R.string.previousPageLabel)
128-
)
129-
}
130111

131-
Slider(
132-
value = currentPage.toFloat(),
133-
valueRange = 0f..(totalPages - 1).toFloat(),
134-
steps = totalPages,
135-
onValueChange = {
136-
currentPageContent = null
137-
onChangePage(it.toInt())
138-
},
139-
modifier = Modifier.weight(0.9f)
112+
Text(
113+
text = pageFilename,
114+
style = MaterialTheme.typography.titleSmall,
115+
textAlign = TextAlign.Center,
116+
maxLines = 1, overflow = TextOverflow.Ellipsis,
117+
modifier = Modifier.fillMaxWidth()
118+
)
119+
Row(modifier = Modifier.fillMaxWidth()) {
120+
IconButton(onClick = {
121+
currentPageContent = null
122+
onChangePage(currentPage - 1)
123+
}, enabled = (currentPage > 0)) {
124+
Icon(
125+
painterResource(R.drawable.ic_previous_page),
126+
contentDescription = stringResource(R.string.previousPageLabel)
140127
)
128+
}
141129

142-
IconButton(onClick = {
130+
Slider(
131+
value = currentPage.toFloat(),
132+
valueRange = 0f..(totalPages - 1).toFloat(),
133+
steps = totalPages,
134+
onValueChange = {
143135
currentPageContent = null
144-
onChangePage(currentPage + 1)
145-
}, enabled = (currentPage < (totalPages - 1))) {
146-
Icon(
147-
painterResource(R.drawable.ic_next_page),
148-
contentDescription = stringResource(R.string.nextPageLabel)
149-
)
150-
}
136+
onChangePage(it.toInt())
137+
},
138+
modifier = Modifier.weight(0.9f)
139+
)
140+
141+
IconButton(onClick = {
142+
currentPageContent = null
143+
onChangePage(currentPage + 1)
144+
}, enabled = (currentPage < (totalPages - 1))) {
145+
Icon(
146+
painterResource(R.drawable.ic_next_page),
147+
contentDescription = stringResource(R.string.nextPageLabel)
148+
)
151149
}
152150
}
153-
},
154-
modifier = modifier
155-
.fillMaxSize()
156-
)
151+
}
152+
153+
154+
if (currentPageContent == null) {
155+
LaunchedEffect(currentPageContent) {
156+
currentPageContent =
157+
ArchiveAPI.loadPage(comicFilename, pageFilename)
158+
}
159+
} else {
160+
currentPageContent?.let { content ->
161+
Image(
162+
bitmap = BitmapFactory.decodeByteArray(content, 0, content.size)
163+
.asImageBitmap(),
164+
contentDescription = title,
165+
modifier = modifier
166+
.fillMaxHeight()
167+
)
168+
}
169+
}
170+
}
157171
}
158172

159173

160174
@Composable
161175
@Preview
162-
fun ReadingPageViewPreview() {
176+
fun PageNavigationPreview() {
163177
val comic = COMIC_BOOK_LIST.get(0)
178+
164179
VariantTheme {
165-
ReadingPageView(
180+
PageNavigationView(
181+
comic.path,
166182
comic.filename,
167183
comic.pages.get(0).filename,
168184
"Page Title",
169185
5,
170186
10,
187+
false,
188+
onChangePage = {},
189+
onStopReading = {},
190+
onToggleShowOverlay = {})
191+
}
192+
}
193+
194+
@Composable
195+
@Preview
196+
fun PageNavigationPreviewWithOverlay() {
197+
val comic = COMIC_BOOK_LIST.get(0)
198+
199+
VariantTheme {
200+
PageNavigationView(
201+
comic.path,
202+
comic.metadata.title,
203+
comic.pages.get(0).filename,
204+
"Page Title",
205+
5,
206+
10,
207+
true,
171208
onChangePage = {},
172-
onStopReading = {}
173-
)
209+
onStopReading = {},
210+
onToggleShowOverlay = {})
174211
}
175212
}

androidVariant/src/main/java/org/comixedproject/variant/android/view/reading/ReadingView.kt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package org.comixedproject.variant.android.view.reading
2121
import androidx.compose.runtime.Composable
2222
import androidx.compose.runtime.getValue
2323
import androidx.compose.runtime.mutableIntStateOf
24+
import androidx.compose.runtime.mutableStateOf
2425
import androidx.compose.runtime.remember
2526
import androidx.compose.runtime.setValue
2627
import androidx.compose.ui.Modifier
@@ -33,20 +34,31 @@ import org.comixedproject.variant.platform.Log
3334
private const val TAG = "ReadingView"
3435

3536
@Composable
36-
fun ReadingView(comicBook: ComicBook, onStopReading: () -> Unit, modifier: Modifier = Modifier) {
37+
fun ReadingView(
38+
comicBook: ComicBook,
39+
onStopReading: () -> Unit,
40+
modifier: Modifier = Modifier
41+
) {
3742
var currentPage by remember { mutableIntStateOf(0) }
43+
var showPageOverlay by remember { mutableStateOf(false) }
3844

39-
ReadingPageView(
45+
PageNavigationView(
4046
comicBook.path,
47+
comicBook.filename,
4148
comicBook.pages.get(currentPage).filename,
4249
comicBook.pages.get(currentPage).filename,
4350
currentPage,
4451
comicBook.pages.size,
52+
showPageOverlay,
4553
onChangePage = {
4654
Log.debug(TAG, "Going to page ${it}")
4755
currentPage = it
4856
},
4957
onStopReading = onStopReading,
58+
onToggleShowOverlay = {
59+
Log.debug(TAG, "Toggling showing overlay")
60+
showPageOverlay = !showPageOverlay
61+
},
5062
modifier = modifier
5163
)
5264
}

iosVariant/Variant.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
6AA5984C2DE72EF40078CC9F /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AA5984B2DE72EF40078CC9F /* Fixtures.swift */; };
1717
6AA598502DE73A8F0078CC9F /* EditServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AA5984F2DE73A8F0078CC9F /* EditServerView.swift */; };
1818
6AF012932E1DDF67001A6A19 /* ReadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AF012922E1DDF67001A6A19 /* ReadingView.swift */; };
19-
6AF012952E1E89A3001A6A19 /* ReadingPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AF012942E1E89A3001A6A19 /* ReadingPageView.swift */; };
2019
7555FF83242A565900829871 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* HomeView.swift */; };
2120
B62AADC32DFDDF01000BCC0C /* DirectoryEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62AADC22DFDDF01000BCC0C /* DirectoryEntry.swift */; };
2221
B67F711E2E1848A1005BFB6B /* ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67F711D2E1848A1005BFB6B /* ImageLoader.swift */; };
@@ -26,6 +25,7 @@
2625
B68FF2E92E0834980010853B /* ComicBooksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68FF2E82E0834980010853B /* ComicBooksView.swift */; };
2726
B68FF2EB2E0834EF0010853B /* ComicBookListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68FF2EA2E0834EF0010853B /* ComicBookListView.swift */; };
2827
B68FF2ED2E0837610010853B /* ComicBookListItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68FF2EC2E0837610010853B /* ComicBookListItemView.swift */; };
28+
B6A363ED2E456E5600E9D270 /* PageNavigationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A363EC2E456E5600E9D270 /* PageNavigationView.swift */; };
2929
B6AEB7952E1024FC003FB705 /* AppDestination.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AEB7942E1024FC003FB705 /* AppDestination.swift */; };
3030
B6AEB7972E102901003FB705 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AEB7962E102901003FB705 /* SettingsView.swift */; };
3131
B6B20B942DE5048E008598A7 /* KMPObservableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B20B932DE5048E008598A7 /* KMPObservableViewModel.swift */; };
@@ -57,7 +57,6 @@
5757
6AA5984B2DE72EF40078CC9F /* Fixtures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fixtures.swift; sourceTree = "<group>"; };
5858
6AA5984F2DE73A8F0078CC9F /* EditServerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditServerView.swift; sourceTree = "<group>"; };
5959
6AF012922E1DDF67001A6A19 /* ReadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadingView.swift; sourceTree = "<group>"; };
60-
6AF012942E1E89A3001A6A19 /* ReadingPageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadingPageView.swift; sourceTree = "<group>"; };
6160
7555FF7B242A565900829871 /* Variant.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Variant.app; sourceTree = BUILT_PRODUCTS_DIR; };
6261
7555FF82242A565900829871 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
6362
7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -69,6 +68,7 @@
6968
B68FF2E82E0834980010853B /* ComicBooksView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComicBooksView.swift; sourceTree = "<group>"; };
7069
B68FF2EA2E0834EF0010853B /* ComicBookListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComicBookListView.swift; sourceTree = "<group>"; };
7170
B68FF2EC2E0837610010853B /* ComicBookListItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComicBookListItemView.swift; sourceTree = "<group>"; };
71+
B6A363EC2E456E5600E9D270 /* PageNavigationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageNavigationView.swift; sourceTree = "<group>"; };
7272
B6AEB7942E1024FC003FB705 /* AppDestination.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDestination.swift; sourceTree = "<group>"; };
7373
B6AEB7962E102901003FB705 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
7474
B6B20B932DE5048E008598A7 /* KMPObservableViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMPObservableViewModel.swift; sourceTree = "<group>"; };
@@ -108,7 +108,7 @@
108108
isa = PBXGroup;
109109
children = (
110110
6AF012922E1DDF67001A6A19 /* ReadingView.swift */,
111-
6AF012942E1E89A3001A6A19 /* ReadingPageView.swift */,
111+
B6A363EC2E456E5600E9D270 /* PageNavigationView.swift */,
112112
);
113113
path = Reading;
114114
sourceTree = "<group>";
@@ -322,6 +322,7 @@
322322
B6B20B9E2DE50C0E008598A7 /* Koin.swift in Sources */,
323323
B68FF2E92E0834980010853B /* ComicBooksView.swift in Sources */,
324324
6A4D18062E14191D00FF9EA2 /* Constants.swift in Sources */,
325+
B6A363ED2E456E5600E9D270 /* PageNavigationView.swift in Sources */,
325326
B68922532DFDC29400BDC032 /* DirectoryItemView.swift in Sources */,
326327
6AA598492DE72E910078CC9F /* ServerView.swift in Sources */,
327328
B6AEB7972E102901003FB705 /* SettingsView.swift in Sources */,
@@ -330,7 +331,6 @@
330331
B6B20B942DE5048E008598A7 /* KMPObservableViewModel.swift in Sources */,
331332
B689224F2DFDA77C00BDC032 /* BrowseServerView.swift in Sources */,
332333
B6AEB7952E1024FC003FB705 /* AppDestination.swift in Sources */,
333-
6AF012952E1E89A3001A6A19 /* ReadingPageView.swift in Sources */,
334334
B68FF2EB2E0834EF0010853B /* ComicBookListView.swift in Sources */,
335335
);
336336
runOnlyForDeploymentPostprocessing = 0;

0 commit comments

Comments
 (0)