Skip to content

Commit

Permalink
Merge pull request #424 from firemaples/refactor/restructure
Browse files Browse the repository at this point in the history
Refactor basics, MainBar and ResultView
  • Loading branch information
firemaples authored Feb 3, 2024
2 parents ab636fb + ae80024 commit 70a92f6
Show file tree
Hide file tree
Showing 55 changed files with 4,656 additions and 1,309 deletions.
10 changes: 9 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ buildscript {
ext.nav_version = "2.6.0" // require SDK 34 from 2.7.0
repositories {
google()
gradlePluginPortal()
mavenCentral()
maven {
url "https://jitpack.io"
Expand All @@ -18,15 +19,22 @@ buildscript {
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.google.gms:google-services:4.4.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20"
classpath 'com.google.firebase:perf-plugin:1.4.2'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'

// Refactor
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"

// Detekt
classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.3"
}
}

plugins {
id 'com.google.dagger.hilt.android' version '2.48' apply false
}

allprojects {
repositories {
google()
Expand Down
85 changes: 85 additions & 0 deletions detekt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# From https://mrmans0n.github.io/compose-rules/detekt/
Compose:
ComposableAnnotationNaming:
active: true
ComposableNaming:
active: true
# -- You can optionally disable the checks in this rule for regex matches against the composable name (e.g. molecule presenters)
# allowedComposableFunctionNames: .*Presenter,.*MoleculePresenter
ComposableParamOrder:
active: true
# -- You can optionally have a list of types to be treated as lambdas (e.g. typedefs or fun interfaces not picked up automatically)
# treatAsLambda: MyLambdaType
CompositionLocalAllowlist:
active: true
# -- You can optionally define a list of CompositionLocals that are allowed here
# allowedCompositionLocals: LocalSomething,LocalSomethingElse
CompositionLocalNaming:
active: true
ContentEmitterReturningValues:
active: true
# -- You can optionally add your own composables here
# contentEmitters: MyComposable,MyOtherComposable
DefaultsVisibility:
active: true
ModifierClickableOrder:
active: true
# -- You can optionally add your own Modifier types
# customModifiers: BananaModifier,PotatoModifier
ModifierComposable:
active: true
# -- You can optionally add your own Modifier types
# customModifiers: BananaModifier,PotatoModifier
ModifierMissing:
active: true
# -- You can optionally control the visibility of which composables to check for here
# -- Possible values are: `only_public`, `public_and_internal` and `all` (default is `only_public`)
# checkModifiersForVisibility: only_public
# -- You can optionally add your own Modifier types
# customModifiers: BananaModifier,PotatoModifier
ModifierNaming:
active: true
# -- You can optionally add your own Modifier types
# customModifiers: BananaModifier,PotatoModifier
ModifierNotUsedAtRoot:
active: true
# -- You can optionally add your own composables here
# contentEmitters: MyComposable,MyOtherComposable
# -- You can optionally add your own Modifier types
# customModifiers: BananaModifier,PotatoModifier
ModifierReused:
active: true
# -- You can optionally add your own Modifier types
# customModifiers: BananaModifier,PotatoModifier
ModifierWithoutDefault:
active: true
MultipleEmitters:
active: true
# -- You can optionally add your own composables here that will count as content emitters
# contentEmitters: MyComposable,MyOtherComposable
# -- You can add composables here that you don't want to count as content emitters (e.g. custom dialogs or modals)
# contentEmittersDenylist: MyNonEmitterComposable
MutableParams:
active: true
MutableStateParam:
active: true
PreviewAnnotationNaming:
active: true
PreviewPublic:
active: true
RememberMissing:
active: true
RememberContentMissing:
active: true
UnstableCollections:
active: true
ViewModelForwarding:
active: true
# -- You can optionally use this rule on things other than types ending in "ViewModel" or "Presenter" (which are the defaults). You can add your own via a regex here:
# allowedStateHolderNames: .*ViewModel,.*Presenter
# -- You can optionally add an allowlist for Composable names that won't be affected by this rule
# allowedForwarding: .*Content,.*FancyStuff
ViewModelInjection:
active: true
# -- You can optionally add your own ViewModel factories here
# viewModelFactories: hiltViewModel,potatoViewModel
32 changes: 31 additions & 1 deletion main/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'com.google.firebase.firebase-perf'
id 'com.google.dagger.hilt.android'
id "io.gitlab.arturbosch.detekt"
}

def buildParams = getGradle().getStartParameter().toString().toLowerCase()
Expand Down Expand Up @@ -91,7 +93,11 @@ android {
jvmTarget = '17'
}
buildFeatures {
viewBinding true
viewBinding true //TODO remove after full migrating to compose
compose true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.4"
}
packagingOptions {
jniLibs {
Expand All @@ -100,7 +106,13 @@ android {
}
}

kapt {
correctErrorTypes true
}

dependencies {
detektPlugins "io.nlopez.compose.rules:detekt:0.3.9"

implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')

implementation 'androidx.core:core-ktx:1.10.1'
Expand All @@ -110,6 +122,7 @@ dependencies {
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.lifecycle:lifecycle-runtime-compose:2.6.2'
implementation "androidx.preference:preference-ktx:1.2.1"
implementation 'androidx.webkit:webkit:1.7.0'
//noinspection GradleDynamicVersion
Expand Down Expand Up @@ -138,6 +151,23 @@ dependencies {
// required to avoid crash on Android 12 API 31
implementation 'androidx.work:work-runtime-ktx:2.8.1'

// Compose
def composeBom = platform('androidx.compose:compose-bom:2023.06.01')
implementation composeBom
androidTestImplementation composeBom
// Material Design 3
implementation 'androidx.compose.material3:material3'
// Android Studio Preview support
implementation 'androidx.compose.ui:ui-tooling-preview'
debugImplementation 'androidx.compose.ui:ui-tooling'
// UI Tests
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
debugImplementation 'androidx.compose.ui:ui-test-manifest'

// Hilt
implementation "com.google.dagger:hilt-android:2.48"
kapt "com.google.dagger:hilt-compiler:2.48"

// Firebase
implementation platform('com.google.firebase:firebase-bom:32.6.0')
implementation 'com.google.firebase:firebase-crashlytics'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package tw.firemaples.onscreenocr

import android.app.Application
import dagger.hilt.android.HiltAndroidApp
import tw.firemaples.onscreenocr.log.FirebaseEvent
import tw.firemaples.onscreenocr.log.UserInfoUtils
import tw.firemaples.onscreenocr.remoteconfig.RemoteConfigManager
import tw.firemaples.onscreenocr.utils.AdManager

@HiltAndroidApp
class CoreApplication : Application() {
companion object {
lateinit var instance: Application
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package tw.firemaples.onscreenocr.data.repo

import android.graphics.Point
import androidx.lifecycle.asFlow
import com.chibatching.kotpref.livedata.asLiveData
import tw.firemaples.onscreenocr.pref.AppPref
import javax.inject.Inject

class PreferenceRepository @Inject constructor() {
fun saveLastMainBarPosition(x: Int, y: Int) {
AppPref.lastMainBarPosition = Point(x, y)
}

fun getLastMainBarPosition(): Point =
AppPref.lastMainBarPosition

fun getShowTextSelectionOnResultView() =
AppPref.asLiveData(AppPref::displaySelectedTextOnResultWindow).asFlow()

fun setShowTextSelectionOnResultView(show: Boolean) {
AppPref.displaySelectedTextOnResultWindow = show
}

fun getResultViewFontSize() =
AppPref.asLiveData(AppPref::resultWindowFontSize).asFlow()

fun setResultViewFontSize(fontSize: Float) {
AppPref.resultWindowFontSize = fontSize
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package tw.firemaples.onscreenocr.data.repo

import androidx.lifecycle.asFlow
import com.chibatching.kotpref.livedata.asLiveData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import tw.firemaples.onscreenocr.pref.AppPref
import tw.firemaples.onscreenocr.recognition.TextRecognitionProviderType
import tw.firemaples.onscreenocr.utils.Constants
import javax.inject.Inject

class RecognitionRepository @Inject constructor() {
val ocrLanguage: Flow<String>
get() = AppPref.asLiveData(AppPref::selectedOCRLang).asFlow()

val ocrProvider: Flow<TextRecognitionProviderType>
get() = AppPref.asLiveData(AppPref::selectedOCRProviderKey).asFlow()
.map { key ->
TextRecognitionProviderType.entries.firstOrNull { it.key == key }
?: Constants.DEFAULT_OCR_PROVIDER
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package tw.firemaples.onscreenocr.data.repo

import tw.firemaples.onscreenocr.pages.setting.SettingManager
import javax.inject.Inject

class SettingRepository @Inject constructor() {
fun shouldRestoreMainBarPosition(): Boolean =
SettingManager.restoreMainBarPosition

fun hideOCRAreaAfterTranslated(): Boolean =
SettingManager.hideRecognizedResultAfterTranslated
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package tw.firemaples.onscreenocr.data.repo

import androidx.lifecycle.asFlow
import com.chibatching.kotpref.livedata.asLiveData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import tw.firemaples.onscreenocr.pref.AppPref
import tw.firemaples.onscreenocr.translator.TranslationProviderType
import javax.inject.Inject

class TranslatorRepository @Inject constructor() {
val currentProviderType: Flow<TranslationProviderType>
get() = AppPref.asLiveData(AppPref::selectedTranslationProvider).asFlow()
.map { TranslationProviderType.fromKey(it) }
val currentTranslationLang: Flow<String>
get() = AppPref.asLiveData(AppPref::selectedTranslationLang).asFlow()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tw.firemaples.onscreenocr.data.usecase

import kotlinx.coroutines.flow.combine
import tw.firemaples.onscreenocr.data.repo.RecognitionRepository
import tw.firemaples.onscreenocr.recognition.TextRecognizer
import javax.inject.Inject

class GetCurrentOCRDisplayLangCodeUseCase @Inject constructor(
private val recognitionRepository: RecognitionRepository,
) {
operator fun invoke() =
recognitionRepository.ocrProvider
.combine(recognitionRepository.ocrLanguage) { provider, lang ->
TextRecognizer.getRecognizer(provider).parseToDisplayLangCode(lang)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package tw.firemaples.onscreenocr.data.usecase

import kotlinx.coroutines.flow.combine
import tw.firemaples.onscreenocr.data.repo.RecognitionRepository
import javax.inject.Inject

class GetCurrentOCRLangUseCase @Inject constructor(
private val recognitionRepository: RecognitionRepository,
) {
operator fun invoke() =
combine(
recognitionRepository.ocrProvider,
recognitionRepository.ocrLanguage,
) { provider, lang -> provider to lang }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package tw.firemaples.onscreenocr.data.usecase

import tw.firemaples.onscreenocr.data.repo.TranslatorRepository
import javax.inject.Inject

class GetCurrentTranslationLangUseCase @Inject constructor(
private val translatorRepository: TranslatorRepository,
) {
operator fun invoke() = translatorRepository.currentTranslationLang
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package tw.firemaples.onscreenocr.data.usecase

import tw.firemaples.onscreenocr.data.repo.TranslatorRepository
import javax.inject.Inject

class GetCurrentTranslatorTypeUseCase @Inject constructor(
private val translatorRepository: TranslatorRepository,
) {
operator fun invoke() = translatorRepository.currentProviderType
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package tw.firemaples.onscreenocr.data.usecase

import tw.firemaples.onscreenocr.data.repo.SettingRepository
import javax.inject.Inject

class GetHidingOCRAreaAfterTranslatedUseCase @Inject constructor(
private val settingRepository: SettingRepository,
) {
operator fun invoke() = settingRepository.hideOCRAreaAfterTranslated()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tw.firemaples.onscreenocr.data.usecase

import android.graphics.Point
import tw.firemaples.onscreenocr.data.repo.PreferenceRepository
import tw.firemaples.onscreenocr.data.repo.SettingRepository
import javax.inject.Inject

class GetMainBarInitialPositionUseCase @Inject constructor(
private val settingRepository: SettingRepository,
private val preferenceRepository: PreferenceRepository,
) {
operator fun invoke() =
if (settingRepository.shouldRestoreMainBarPosition())
preferenceRepository.getLastMainBarPosition()
else Point(0, 0)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package tw.firemaples.onscreenocr.data.usecase

import tw.firemaples.onscreenocr.data.repo.PreferenceRepository
import javax.inject.Inject

class GetResultViewFontSizeUseCase @Inject constructor(
private val preferenceRepository: PreferenceRepository,
) {
operator fun invoke() = preferenceRepository.getResultViewFontSize()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package tw.firemaples.onscreenocr.data.usecase

import tw.firemaples.onscreenocr.data.repo.PreferenceRepository
import javax.inject.Inject

class GetShowTextSelectorOnResultViewUseCase @Inject constructor(
private val preferenceRepository: PreferenceRepository,
) {
operator fun invoke() = preferenceRepository.getShowTextSelectionOnResultView()
}
Loading

0 comments on commit 70a92f6

Please sign in to comment.