Skip to content

Commit

Permalink
Merge branch 'dev' into 'main'
Browse files Browse the repository at this point in the history
v1.9.0
  • Loading branch information
nsh07 committed Dec 29, 2024
2 parents 512a84d + dd7773c commit d2f89c0
Show file tree
Hide file tree
Showing 35 changed files with 954 additions and 103 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Supports light mode, dark mode, Material You dynamic colors and 300+ Wikipedia l
and view in full-screen
- **Random article:** Feeling lucky? Click the random article button to read a random article
- **Choose your language:** Choose from over 300 languages on Wikipedia
- **Save articles:** Download articles to your device for offline reading
- **One-handed use:** Use the floating action buttons at the bottom for a complete one-handed
experience
- **Lightweight:** The app starts instantly, and works smoothly
Expand All @@ -65,6 +66,7 @@ Supports light mode, dark mode, Material You dynamic colors and 300+ Wikipedia l
- **Customizable colors:** Choose from light/dark themes and customize the Material 3 color palette
- **Customizable font size:** Choose your own comfortable font size
- **Data saver:** Save your limited data plan by loading text only
- **Math expressions:** View properly rendered mathematical expressions for easily reading mathematical articles

## Special Thanks

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ android {
applicationId = "org.nsh07.wikireader"
minSdk = 26
targetSdk = 35
versionCode = 19
versionName = "1.8.3"
versionCode = 20
versionName = "1.9.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/org/nsh07/wikireader/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class MainActivity : ComponentActivity() {
installSplashScreen().setKeepOnScreenCondition {
!viewModel.isReady || !viewModel.isAnimDurationComplete
}
viewModel.setFilesDir(filesDir.path)
enableEdgeToEdge()

setContent {
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/java/org/nsh07/wikireader/data/WRStatus.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.nsh07.wikireader.data

enum class WRStatus {
SUCCESS, NETWORK_ERROR, IO_ERROR, NO_SEARCH_RESULT, UNINITIALIZED, OTHER
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ data class WikiApiQuery(
data class WikiApiPage(
val title: String,
val extract: String,
@SerialName(value = "pageid") val pageId: Int? = null,
@SerialName(value = "original") val photo: WikiPhoto? = null,
@SerialName(value = "terms") val photoDesc: WikiPhotoDesc? = null,
@SerialName(value = "langlinks") val langs: List<WikiLang>? = null
Expand Down
19 changes: 17 additions & 2 deletions app/src/main/java/org/nsh07/wikireader/data/parsers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,27 @@ fun parseText(text: String): List<String> {
return out
}

fun bytesToHumanReadableSize(bytes: Double) = when {
bytes >= 1 shl 30 -> "%.1f GB".format(bytes / (1 shl 30))
bytes >= 1 shl 20 -> "%.1f MB".format(bytes / (1 shl 20))
bytes >= 1 shl 10 -> "%.0f kB".format(bytes / (1 shl 10))
else -> "$bytes bytes"
}

fun langCodeToName(langCode: String): String {
Log.d("Language", "CodeToName called")
try {
return LanguageData.langNames[LanguageData.langCodes.binarySearch(langCode)]
} catch(_: Exception) {
Log.e("Language", "Unknown Language: $langCode")
return "Unknown Language: $langCode"
return langCode
}
}

fun langCodeToWikiName(langCode: String): String {
try {
return LanguageData.wikipediaNames[LanguageData.langCodes.binarySearch(langCode)]
} catch(_: Exception) {
Log.e("Language", "Unknown Language: $langCode")
return langCode
}
}
66 changes: 57 additions & 9 deletions app/src/main/java/org/nsh07/wikireader/ui/AppScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
Expand All @@ -48,12 +50,15 @@ import coil3.ImageLoader
import coil3.gif.AnimatedImageDecoder
import coil3.gif.GifDecoder
import coil3.svg.SvgDecoder
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.nsh07.wikireader.data.WRStatus
import org.nsh07.wikireader.ui.aboutScreen.AboutScreen
import org.nsh07.wikireader.ui.homeScreen.AppFab
import org.nsh07.wikireader.ui.homeScreen.AppHomeScreen
import org.nsh07.wikireader.ui.homeScreen.AppSearchBar
import org.nsh07.wikireader.ui.image.FullScreenImage
import org.nsh07.wikireader.ui.savedArticlesScreen.SavedArticlesScreen
import org.nsh07.wikireader.ui.settingsScreen.SettingsScreen
import org.nsh07.wikireader.ui.viewModel.PreferencesState
import org.nsh07.wikireader.ui.viewModel.UiViewModel
Expand Down Expand Up @@ -84,6 +89,7 @@ fun AppScreen(
.build()

val coroutineScope = rememberCoroutineScope()
val snackBarHostState = remember { SnackbarHostState() }

val index by remember { derivedStateOf { listState.firstVisibleItemIndex } }
val (showDeleteDialog, setShowDeleteDialog) = remember { mutableStateOf(false) }
Expand Down Expand Up @@ -140,7 +146,11 @@ fun AppScreen(

BackHandler(!homeScreenState.isBackStackEmpty) {
val curr = viewModel.popBackStack()
viewModel.performSearch(query = curr?.first, lang = curr?.second, fromBackStack = true)
viewModel.performSearch(
query = curr?.first,
lang = curr?.second,
fromBackStack = true
)
}

if (showDeleteDialog)
Expand Down Expand Up @@ -169,12 +179,16 @@ fun AppScreen(
setHistoryItem(it)
setShowDeleteDialog(true)
},
onSavedArticlesClick = {
navController.navigate("savedArticles")
it(false)
},
onSettingsClick = {
navController.navigate("Settings")
navController.navigate("settings")
it(false)
},
onAboutClick = {
navController.navigate("About")
navController.navigate("about")
it(false)
},
modifier = Modifier.padding(
Expand All @@ -184,17 +198,18 @@ fun AppScreen(
},
floatingActionButton = {
AppFab(
index = index,
focusSearch = { viewModel.focusSearchBar() },
scrollToTop = { coroutineScope.launch { listState.animateScrollToItem(0) } },
performRandomPageSearch = {
viewModel.performSearch(
query = null,
random = true
)
},
index = index
}
)
},
snackbarHost = { SnackbarHost(snackBarHostState) },
modifier = Modifier.fillMaxSize()
) { insets ->
AppHomeScreen(
Expand All @@ -207,21 +222,40 @@ fun AppScreen(
showLanguageSheet = showArticleLanguageSheet,
onImageClick = {
if (homeScreenState.photo != null)
navController.navigate("FullScreenImage")
navController.navigate("fullScreenImage")
},
insets = insets,
onLinkClick = { viewModel.performSearch(it, fromLink = true) },
refreshSearch = { viewModel.refreshSearch(true) },
setLang = { viewModel.saveLang(it) },
setSearchStr = { viewModel.updateLanguageSearchStr(it) },
setShowArticleLanguageSheet = { showArticleLanguageSheet = it },
saveArticle = {
coroutineScope.launch {
if (!homeScreenState.isSaved) {
val status = viewModel.saveArticle()
if (status == WRStatus.SUCCESS)
snackBarHostState.showSnackbar("Article saved for offline reading")
else
snackBarHostState.showSnackbar("Unable to save article: ${status.name}")
delay(150L)
} else {
val status = viewModel.deleteArticle()
if (status == WRStatus.SUCCESS)
snackBarHostState.showSnackbar("Article deleted")
else
snackBarHostState.showSnackbar("Unable to delete article: ${status.name}")
}
}
},
modifier = Modifier
.fillMaxSize()
.padding(top = insets.calculateTopPadding())
)
}
}

composable("FullScreenImage") {
composable("fullScreenImage") {
if (homeScreenState.photo == null) navController.navigateUp()
FullScreenImage(
photo = homeScreenState.photo,
Expand All @@ -231,15 +265,29 @@ fun AppScreen(
)
}

composable("Settings") {
composable("savedArticles") {
SavedArticlesScreen(
loadArticles = { viewModel.listArticles() },
openSavedArticle = {
viewModel.loadSavedArticle(it)
navController.navigateUp()
},
articlesSize = { viewModel.totalArticlesSize() },
deleteArticle = { viewModel.deleteArticle(it) },
deleteAll = { viewModel.deleteAllArticles() },
onBack = { navController.navigateUp() }
)
}

composable("settings") {
SettingsScreen(
preferencesState = preferencesState,
onBack = { navController.navigateUp() },
viewModel = viewModel
)
}

composable("About") {
composable("about") {
AboutScreen(
onBack = { navController.navigateUp() }
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import org.nsh07.wikireader.R

@Composable
fun AppFab(
index: Int,
focusSearch: () -> Unit,
scrollToTop: () -> Unit,
performRandomPageSearch: () -> Unit,
index: Int
performRandomPageSearch: () -> Unit
) {
Column(horizontalAlignment = Alignment.End) {
SmallFloatingActionButton(
Expand Down
Loading

0 comments on commit d2f89c0

Please sign in to comment.