├── .gitignore ├── Changelog.md ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle.kts ├── proguard-rules.pro ├── schemas │ └── com.machiav3lli.derdiedas.data.NounDatabase │ │ └── 1.json └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── machiav3lli │ │ └── derdiedas │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ │ └── com │ │ │ └── machiav3lli │ │ │ └── derdiedas │ │ │ ├── Constants.kt │ │ │ ├── data │ │ │ ├── Noun.kt │ │ │ ├── NounDao.kt │ │ │ ├── NounDatabase.kt │ │ │ ├── SpacedRepetitionModel.kt │ │ │ └── WordViewModel.kt │ │ │ ├── ui │ │ │ ├── BaseActivity.kt │ │ │ ├── MainActivity.kt │ │ │ ├── SettingsActivity.kt │ │ │ ├── SettingsFragment.kt │ │ │ ├── StatsActivity.kt │ │ │ ├── WordActivity.kt │ │ │ └── WordFragment.kt │ │ │ └── utils │ │ │ ├── AnimationUtil.kt │ │ │ ├── ContextUtil.kt │ │ │ ├── DatabaseUtil.kt │ │ │ ├── FileUtils.kt │ │ │ ├── LanguagePref.kt │ │ │ ├── NounUtils.kt │ │ │ └── PrefsUtil.kt │ └── res │ │ ├── anim │ │ ├── jump_animation.xml │ │ └── wait_animation.xml │ │ ├── drawable │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_launcher_foreground_mc.xml │ │ ├── ic_round_arrow_back_32.xml │ │ └── ic_round_help_outline_24.xml │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_settings.xml │ │ ├── activity_stats.xml │ │ ├── activity_word.xml │ │ └── fragment_word.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ │ ├── raw │ │ └── list_nouns.txt │ │ ├── values-eo │ │ └── strings.xml │ │ ├── values-es │ │ └── strings.xml │ │ ├── values-fr │ │ └── strings.xml │ │ ├── values-hi │ │ └── strings.xml │ │ ├── values-it │ │ └── strings.xml │ │ ├── values-ko │ │ └── strings.xml │ │ ├── values-nb-rNO │ │ └── strings.xml │ │ ├── values-night │ │ ├── colors.xml │ │ └── styles.xml │ │ ├── values-nl │ │ └── strings.xml │ │ ├── values-notnight │ │ └── styles.xml │ │ ├── values-pl │ │ └── strings.xml │ │ ├── values-pt-rBR │ │ └── strings.xml │ │ ├── values-ru │ │ └── strings.xml │ │ ├── values-tr │ │ └── strings.xml │ │ ├── values-uk │ │ └── strings.xml │ │ ├── values-zh-rCN │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── ic_launcher_background.xml │ │ └── strings.xml │ │ └── xml │ │ └── preferences.xml │ └── test │ └── java │ └── com │ └── machiav3lli │ └── derdiedas │ └── ExampleUnitTest.java ├── badge_github.png ├── build.gradle.kts ├── fastlane └── metadata │ └── android │ ├── de │ └── short_description.txt │ └── en-US │ ├── changelogs │ ├── 1100.txt │ ├── 1101.txt │ ├── 1102.txt │ ├── 1201.txt │ ├── 2000.txt │ ├── 2001.txt │ ├── 2002.txt │ ├── 2003.txt │ ├── 2100.txt │ ├── 2101.txt │ └── 2200.txt │ ├── full_description.txt │ ├── images │ ├── icon.png │ └── phoneScreenshots │ │ ├── 1.png │ │ ├── 2.png │ │ ├── 3.png │ │ └── 4.png │ └── short_description.txt ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.pyc 3 | .gradle 4 | .idea 5 | build 6 | local.properties 7 | /app/release 8 | -------------------------------------------------------------------------------- /Changelog.md: -------------------------------------------------------------------------------- 1 | changelog 2 | ========= 3 | 2.2.0 (12.09.2023) 4 | ------------------ 5 | * Add: Translations 1201→1300 6 | * Update: Material 3 design 7 | * Update CompileSDK 34 8 | * 10+ translations 9 | 10 | 2.1.1 (26.02.2023) 11 | ------------------ 12 | * Add: Show right article beside word after clicking 13 | * Add: New icon 14 | * 40+ translation contributions 15 | 16 | 2.1.0 (12.05.2022) 17 | ------------------ 18 | * Add: 200 words' translations (total 1200) 19 | * Add: Languages setting 20 | * Update translations: Polish, Ukrainian, Russian, French, Norwegian 21 | * Update: Target- and CompileSDK 32 22 | + other small fixes 23 | 24 | 2.0.3 (13.10.2021) 25 | ------------------ 26 | * Update: Target- and CompiledSDK 31 27 | * Add: Words' translation till 1000th 28 | * Update: Dependencies & Gradle 29 | 30 | 2.0.2 (30.07.2021) 31 | ------------------ 32 | * Update: Start again instead of returning back to the main menu 33 | * Fix: Clearing the nouns list on double clicking a choice 34 | * Add: Words' translation till 500th 35 | * Add: Translations to French, Norwegian, Spanish & Italian 36 | * Update: Dependencies & Gradle 37 | 38 | 2.0.1 (19.07.2021) 39 | ------------------ 40 | * Add: WordViewModel. 41 | * Add: Choice to restart when all the words are fully learned. 42 | * Fix: Crashing on practice & stats 43 | * Update: Convert DatabaseUtil to file and abstract creating noun list out of the into it 44 | 45 | 2.0.0 (14.07.2021) 46 | ------------------- 47 | * Update: Migrate to a RoomDatabase 48 | * Add: Nouns translations (300 for now) 49 | * Update: Migrate to Kotlin 50 | * Fix: Bad strings 51 | * Punch of small fixes and improvments 52 | 53 | 1.2.1 (19.03.2021) 54 | ------------------- 55 | * Updated: More mainstream colors 56 | * Fixed: Crash on click stats info 57 | * Fixed: Button's text size not fitting in all screens 58 | * Some code and UI cleaned up 59 | 60 | 1.2.0 (18.06.2020) 61 | ------------------- 62 | * fixed: theme not being applied in Main 63 | * migrated: to private preferences 64 | * some UI optimizations 65 | 66 | 1.1.1 (06.06.2020) 67 | ------------------- 68 | * fixed: crashing settings 69 | * added: back button 70 | * fixed: applying theme on resume 71 | 72 | 1.1.0 (04.06.2020) 73 | ------------------- 74 | * added: new App Icon 75 | * added: Dark Theme comatible with System Theme 76 | * updated: cleaner UI 77 | * and some other tweaks 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 digitapex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Der Die Das 2 | 3 | Android app for learning German nouns genders. 4 | 5 | Contains almost 10,000 German nouns. 6 | 7 | [Get it on F-Droid](https://f-droid.org/packages/com.machiav3lli.derdiedas/) 10 | [Get it on F-Droid](https://apt.izzysoft.de/fdroid/index/apk/com.machiav3lli.derdiedas) 13 | 14 | Otherwise, you can download the apk from the [releases](https://github.com/machiav3lli/DerDieDas/releases). 15 | 16 | ## Screenshots 17 | 18 | ### Dark Theme 19 | 20 |

21 | 22 | 23 |

24 | 25 | ### Light Theme 26 | 27 |

28 | 29 | 30 |

31 | 32 | ## Translations [Translations' state](https://hosted.weblate.org/engage/derdiedas/) 33 | 34 | [![Translations' state](https://hosted.weblate.org/widgets/derdiedas/-/multi-auto.svg)](https://hosted.weblate.org/engage/derdiedas/) 35 | 36 | ## Credits 37 | 38 | [Digitapex](https://github.com/digitapex) for writting this app at the first place. 39 | 40 | ## Donations 41 | 42 | I, myself acknowledge the role of the donations to motivate the work on FOSS projects, but in the state of how dynamic everything around my FOSS-contributions is, I would prefer to not take donations for now (the same answer as the last years). Nevertheless this project wouldn't have the accessibility it has without translations, which you the community drive and for which Weblate provides a platform. That's why I would you suggest you to consider [donating to Weblate](https://weblate.org/donate). 43 | 44 | ## author 45 | 46 | Antonios Hazim 47 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.android.build.gradle.internal.tasks.factory.dependsOn 2 | 3 | plugins { 4 | id("com.android.application") 5 | kotlin("android") 6 | id("com.google.devtools.ksp") version ("1.9.10-1.0.13") 7 | } 8 | 9 | val vKotlin = "1.9.10" 10 | val vKSP = "1.0.13" 11 | val vLifecycle = "2.6.2" 12 | val vMaterial = "1.10.0" 13 | val vPreference = "1.2.1" 14 | val vRoom = "2.6.0-rc01" 15 | 16 | android { 17 | namespace = "com.machiav3lli.derdiedas" 18 | 19 | compileSdk = 34 20 | defaultConfig { 21 | applicationId = "com.machiav3lli.derdiedas" 22 | minSdk = 24 23 | targetSdk = 33 24 | versionCode = 2200 25 | versionName = "2.2.0" 26 | 27 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 28 | 29 | javaCompileOptions { 30 | annotationProcessorOptions { 31 | ksp { 32 | arg("room.schemaLocation", "$projectDir/schemas") 33 | arg("room.incremental", "true") 34 | } 35 | } 36 | } 37 | } 38 | 39 | buildTypes { 40 | named("release") { 41 | proguardFiles( 42 | getDefaultProguardFile("proguard-android-optimize.txt"), 43 | "proguard-rules.pro" 44 | ) 45 | isMinifyEnabled = true 46 | } 47 | named("debug") { 48 | applicationIdSuffix = ".debug" 49 | isMinifyEnabled = false 50 | } 51 | } 52 | buildFeatures { 53 | viewBinding = true 54 | } 55 | compileOptions { 56 | sourceCompatibility = JavaVersion.VERSION_17 57 | targetCompatibility = JavaVersion.VERSION_17 58 | } 59 | dependenciesInfo { 60 | includeInApk = false 61 | includeInBundle = false 62 | } 63 | } 64 | 65 | dependencies { 66 | implementation(kotlin("stdlib", vKotlin)) 67 | implementation("com.google.devtools.ksp:symbol-processing-api:$vKotlin-$vKSP") 68 | 69 | //Libs 70 | implementation("androidx.room:room-runtime:$vRoom") 71 | implementation("androidx.room:room-ktx:$vRoom") 72 | ksp("androidx.room:room-compiler:$vRoom") 73 | implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$vLifecycle") 74 | 75 | // UI 76 | implementation("androidx.preference:preference-ktx:$vPreference") 77 | implementation("com.google.android.material:material:$vMaterial") 78 | 79 | // Test 80 | implementation("androidx.test.ext:junit:1.1.5") 81 | implementation("androidx.test.espresso:espresso-core:3.5.1") 82 | } 83 | 84 | // using a task as a preBuild dependency instead of a function that takes some time insures that it runs 85 | task("detectAndroidLocals") { 86 | val langsList: MutableSet = HashSet() 87 | 88 | // in /res are (almost) all languages that have a translated string is saved. this is safer and saves some time 89 | fileTree("src/main/res").visit { 90 | if (this.file.path.endsWith("strings.xml") 91 | && this.file.canonicalFile.readText().contains("Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.machiav3lli.derdasdie", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/Constants.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas 2 | 3 | const val PREFS_SHARED = "com.machiav3lli.derdiedas" 4 | const val PREFS_THEME = "themes" 5 | const val PREFS_LANG = "language" 6 | const val PREFS_LANG_SYSTEM = "system" 7 | const val NOUN_DB_NAME = "nouns.db" 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/data/Noun.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.data 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | @Entity 7 | class Noun(val noun: String, val gender: String, var timesAnswered: Int) { 8 | @PrimaryKey(autoGenerate = true) 9 | var id: Long = 0 10 | 11 | fun withID(id: Long): Noun { 12 | this.id = id 13 | return this 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/data/NounDao.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.data 2 | 3 | import android.database.SQLException 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.Query 7 | import androidx.room.Update 8 | 9 | @Dao 10 | interface NounDao { 11 | @get:Query("SELECT COUNT(*) FROM noun") 12 | val count: Long 13 | 14 | @Insert 15 | @Throws(SQLException::class) 16 | fun insert(vararg nouns: Noun) 17 | 18 | @Insert 19 | @Throws(SQLException::class) 20 | fun insert(nouns: List) 21 | 22 | @get:Query("SELECT * FROM noun") 23 | val all: MutableList 24 | 25 | @Update 26 | fun update(noun: Noun) 27 | 28 | @Update 29 | fun update(nouns: List) 30 | 31 | @Query("DELETE FROM noun") 32 | fun deleteAll() 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/data/NounDatabase.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.data 2 | 3 | import android.content.Context 4 | import androidx.room.Database 5 | import androidx.room.Room 6 | import androidx.room.RoomDatabase 7 | import com.machiav3lli.derdiedas.NOUN_DB_NAME 8 | 9 | @Database(entities = [Noun::class], version = 1) 10 | abstract class NounDatabase : RoomDatabase() { 11 | abstract val nounDao: NounDao 12 | 13 | companion object { 14 | @Volatile 15 | private var INSTANCE: NounDatabase? = null 16 | 17 | fun getInstance(context: Context): NounDatabase { 18 | synchronized(this) { 19 | if (INSTANCE == null) { 20 | INSTANCE = Room 21 | .databaseBuilder( 22 | context.applicationContext, 23 | NounDatabase::class.java, 24 | NOUN_DB_NAME 25 | ) 26 | .fallbackToDestructiveMigration() 27 | .allowMainThreadQueries() 28 | .build() 29 | } 30 | return INSTANCE!! 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/data/SpacedRepetitionModel.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.data 2 | 3 | fun MutableList.getUpdatedNounList(noun: Noun, isCorrect: Boolean): MutableList { 4 | if (isEmpty()) return mutableListOf() 5 | 6 | removeAt(0) 7 | if (!isCorrect) { 8 | noun.timesAnswered = 0 9 | add(REPETITION_FOR_WRONG.coerceAtMost(size), noun) 10 | } else { 11 | noun.timesAnswered = noun.timesAnswered + 1 12 | if (noun.timesAnswered < TIMES_TO_ANSWER_TO_REMOVE) { 13 | add(REPETITION_FOR_CORRECT.coerceAtMost(size), noun) 14 | } 15 | } 16 | return this 17 | } 18 | 19 | private const val REPETITION_FOR_WRONG = 10 20 | private const val REPETITION_FOR_CORRECT = 20 21 | private const val TIMES_TO_ANSWER_TO_REMOVE = 5 -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/data/WordViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.data 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.* 5 | import kotlinx.coroutines.Dispatchers 6 | import kotlinx.coroutines.launch 7 | import kotlinx.coroutines.withContext 8 | 9 | class WordViewModel(private val nounDao: NounDao, application: Application) : 10 | AndroidViewModel(application) { 11 | var allNouns = MutableLiveData>() 12 | 13 | init { 14 | refreshList() 15 | } 16 | 17 | private fun refreshList() { 18 | viewModelScope.launch { 19 | allNouns.value = nounDao.all 20 | } 21 | } 22 | 23 | fun updateAllNouns(newList: List) { 24 | viewModelScope.launch { 25 | allNouns.value = newList.toMutableList() 26 | updateList(newList) 27 | } 28 | } 29 | 30 | private suspend fun updateList(newList: List) { 31 | withContext(Dispatchers.IO) { 32 | nounDao.deleteAll() 33 | nounDao.insert(newList) 34 | } 35 | } 36 | 37 | class Factory( 38 | private val database: NounDao, 39 | private val application: Application 40 | ) : ViewModelProvider.Factory { 41 | @Suppress("unchecked_cast") 42 | override fun create(modelClass: Class): T { 43 | if (modelClass.isAssignableFrom(WordViewModel::class.java)) { 44 | return WordViewModel(database, application) as T 45 | } 46 | throw IllegalArgumentException("Unknown ViewModel class") 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.content.Context 4 | import androidx.appcompat.app.AppCompatActivity 5 | import com.machiav3lli.derdiedas.utils.wrap 6 | 7 | open class BaseActivity : AppCompatActivity() { 8 | override fun attachBaseContext(newBase: Context) { 9 | super.attachBaseContext(newBase.wrap()) 10 | } 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import androidx.appcompat.app.AppCompatDelegate 6 | import androidx.preference.PreferenceManager 7 | import com.machiav3lli.derdiedas.data.NounDatabase 8 | import com.machiav3lli.derdiedas.databinding.ActivityMainBinding 9 | import com.machiav3lli.derdiedas.utils.appTheme 10 | import com.machiav3lli.derdiedas.utils.createNounListFromAsset 11 | 12 | class MainActivity : BaseActivity() { 13 | private lateinit var binding: ActivityMainBinding 14 | 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | setDayNightTheme(appTheme) 17 | super.onCreate(savedInstanceState) 18 | binding = ActivityMainBinding.inflate(layoutInflater) 19 | setContentView(binding.root) 20 | val prefs = PreferenceManager.getDefaultSharedPreferences(this) 21 | if (prefs.getBoolean("firstrun", true)) { 22 | Thread { 23 | NounDatabase.getInstance(this).let { 24 | it.nounDao.deleteAll() 25 | it.nounDao.insert(createNounListFromAsset()) 26 | } 27 | }.start() 28 | prefs.edit().putBoolean("firstrun", false).apply() 29 | } 30 | } 31 | 32 | override fun onStart() { 33 | super.onStart() 34 | setupOnClicks() 35 | } 36 | 37 | private fun setupOnClicks() { 38 | binding.practice.setOnClickListener { 39 | startActivity(Intent(baseContext, WordActivity::class.java)) 40 | } 41 | binding.stats.setOnClickListener { 42 | startActivity(Intent(baseContext, StatsActivity::class.java)) 43 | } 44 | binding.settings.setOnClickListener { 45 | startActivity(Intent(baseContext, SettingsActivity::class.java)) 46 | } 47 | } 48 | 49 | private fun setDayNightTheme(theme: String?) { 50 | when (theme) { 51 | "light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) 52 | "dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 53 | else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/SettingsActivity.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.os.Bundle 4 | import com.machiav3lli.derdiedas.R 5 | import com.machiav3lli.derdiedas.databinding.ActivitySettingsBinding 6 | 7 | class SettingsActivity : BaseActivity() { 8 | private lateinit var binding: ActivitySettingsBinding 9 | 10 | override fun onCreate(savedInstanceState: Bundle?) { 11 | super.onCreate(savedInstanceState) 12 | binding = ActivitySettingsBinding.inflate(layoutInflater) 13 | setContentView(binding.root) 14 | supportFragmentManager 15 | .beginTransaction() 16 | .add(R.id.fragment_container, SettingsFragment()) 17 | .commit() 18 | binding.back.setOnClickListener { onBackPressed() } 19 | } 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/SettingsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatDelegate 5 | import androidx.preference.ListPreference 6 | import androidx.preference.Preference 7 | import androidx.preference.PreferenceFragmentCompat 8 | import com.machiav3lli.derdiedas.PREFS_LANG 9 | import com.machiav3lli.derdiedas.PREFS_THEME 10 | import com.machiav3lli.derdiedas.R 11 | import com.machiav3lli.derdiedas.utils.appTheme 12 | import com.machiav3lli.derdiedas.utils.language 13 | import com.machiav3lli.derdiedas.utils.restartApp 14 | 15 | class SettingsFragment : PreferenceFragmentCompat() { 16 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { 17 | setPreferencesFromResource(R.xml.preferences, rootKey) 18 | findPreference(PREFS_THEME)?.onPreferenceChangeListener = 19 | Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any -> 20 | requireContext().appTheme = newValue.toString() 21 | when (newValue.toString()) { 22 | "light" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) 23 | "dark" -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES) 24 | else -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) 25 | } 26 | true 27 | } 28 | 29 | findPreference(PREFS_LANG)?.apply { 30 | val oldLang = value 31 | onPreferenceChangeListener = 32 | Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any -> 33 | val changed = oldLang != newValue.toString() 34 | if (changed) { 35 | requireContext().language = newValue.toString() 36 | requireContext().restartApp() 37 | } 38 | changed 39 | } 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/StatsActivity.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.os.Bundle 4 | import android.widget.TextView 5 | import androidx.appcompat.app.AlertDialog 6 | import com.machiav3lli.derdiedas.R 7 | import com.machiav3lli.derdiedas.databinding.ActivityStatsBinding 8 | import com.machiav3lli.derdiedas.utils.FileUtils.getNounsCount 9 | import com.machiav3lli.derdiedas.utils.getNounsCount 10 | import java.io.UnsupportedEncodingException 11 | import java.util.* 12 | 13 | class StatsActivity : BaseActivity() { 14 | private lateinit var binding: ActivityStatsBinding 15 | 16 | override fun onCreate(savedInstanceState: Bundle?) { 17 | super.onCreate(savedInstanceState) 18 | binding = ActivityStatsBinding.inflate(layoutInflater) 19 | setContentView(binding.root) 20 | try { 21 | setWordStats() 22 | } catch (e: UnsupportedEncodingException) { 23 | e.printStackTrace() 24 | } 25 | binding.back.setOnClickListener { onBackPressed() } 26 | binding.statsInfo.setOnClickListener { onFullWords() } 27 | } 28 | 29 | @Throws(UnsupportedEncodingException::class) 30 | private fun setWordStats() { 31 | val allNouns = getNounsCount(this) 32 | Thread { 33 | val remainingNouns = this.getNounsCount() 34 | val learnedWords = allNouns - remainingNouns 35 | runOnUiThread { 36 | findViewById(R.id.word_stats).text = 37 | String.format(Locale.ENGLISH, "%d / %d", learnedWords, allNouns) 38 | } 39 | }.start() 40 | } 41 | 42 | private fun onFullWords() { 43 | val titleString = resources.getString(R.string.full_words_title) 44 | val textString = resources.getString(R.string.full_words_text) 45 | val builder = AlertDialog.Builder(this, R.style.AlertDialogCustom) 46 | builder.setTitle(titleString) 47 | builder.setMessage(textString) 48 | builder.setPositiveButton("OK", null) 49 | val dialog = builder.create() 50 | dialog.show() 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/WordActivity.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.os.Bundle 4 | import androidx.lifecycle.ViewModelProvider 5 | import com.machiav3lli.derdiedas.R 6 | import com.machiav3lli.derdiedas.data.Noun 7 | import com.machiav3lli.derdiedas.data.NounDatabase 8 | import com.machiav3lli.derdiedas.data.WordViewModel 9 | import com.machiav3lli.derdiedas.databinding.ActivityWordBinding 10 | 11 | class WordActivity : BaseActivity() { 12 | private lateinit var binding: ActivityWordBinding 13 | private lateinit var viewModel: WordViewModel 14 | var allNouns: MutableList 15 | get() = viewModel.allNouns.value ?: mutableListOf() 16 | set(value) { 17 | viewModel.updateAllNouns(value) 18 | } 19 | 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | binding = ActivityWordBinding.inflate(layoutInflater) 23 | val nounDao = NounDatabase.getInstance(this).nounDao 24 | val viewModelFactory = WordViewModel.Factory(nounDao, application) 25 | viewModel = ViewModelProvider(this, viewModelFactory).get(WordViewModel::class.java) 26 | supportFragmentManager 27 | .beginTransaction() 28 | .add(R.id.fragment_container, WordFragment()).commit() 29 | setContentView(binding.root) 30 | } 31 | 32 | override fun onStart() { 33 | super.onStart() 34 | binding.back.setOnClickListener { onBackPressed() } 35 | } 36 | 37 | fun replaceFragment() { 38 | val fragmentTransaction = supportFragmentManager.beginTransaction() 39 | fragmentTransaction.setCustomAnimations( 40 | android.R.anim.slide_in_left, 41 | android.R.anim.slide_out_right 42 | ) 43 | fragmentTransaction.replace(R.id.fragment_container, WordFragment()) 44 | fragmentTransaction.commit() 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/ui/WordFragment.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.ui 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.fragment.app.Fragment 8 | import com.google.android.material.button.MaterialButton 9 | import com.machiav3lli.derdiedas.R 10 | import com.machiav3lli.derdiedas.data.Noun 11 | import com.machiav3lli.derdiedas.data.getUpdatedNounList 12 | import com.machiav3lli.derdiedas.databinding.FragmentWordBinding 13 | import com.machiav3lli.derdiedas.utils.AnimationUtil.animateButtonDrawable 14 | import com.machiav3lli.derdiedas.utils.AnimationUtil.animateJumpAndSlide 15 | import com.machiav3lli.derdiedas.utils.createNounListFromAsset 16 | import com.machiav3lli.derdiedas.utils.getStringByName 17 | import com.machiav3lli.derdiedas.utils.updateIds 18 | 19 | class WordFragment : Fragment(), View.OnClickListener { 20 | private var currentNoun: Noun? = null 21 | private var correctGender: String? = null 22 | private lateinit var binding: FragmentWordBinding 23 | private val wordActivity: WordActivity 24 | get() = (requireActivity() as WordActivity) 25 | 26 | private var firstClickBoolean = true 27 | 28 | override fun onCreateView( 29 | inflater: LayoutInflater, 30 | container: ViewGroup?, 31 | savedInstanceState: Bundle? 32 | ): View { 33 | super.onCreate(savedInstanceState) 34 | binding = FragmentWordBinding.inflate(inflater, container, false) 35 | binding.m.setOnClickListener(this) 36 | binding.n.setOnClickListener(this) 37 | binding.f.setOnClickListener(this) 38 | if (wordActivity.allNouns.isNotEmpty()) 39 | currentNoun = wordActivity.allNouns[0] 40 | return binding.root 41 | } 42 | 43 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 44 | super.onViewCreated(view, savedInstanceState) 45 | if (currentNoun != null) { 46 | val noun = currentNoun!!.noun 47 | correctGender = currentNoun!!.gender 48 | binding.nounText.text = noun 49 | binding.translatedText.text = requireContext().getStringByName(noun) 50 | } else { 51 | binding.nounText.text = getString(R.string.finished) 52 | binding.translatedText.text = null 53 | binding.m.text = getString(R.string.dialog_yes) 54 | binding.m.setOnClickListener { 55 | wordActivity.allNouns = 56 | requireContext().createNounListFromAsset() 57 | (requireActivity() as WordActivity).replaceFragment() 58 | } 59 | binding.f.text = getString(R.string.dialog_no) 60 | binding.f.setOnClickListener { 61 | requireActivity().onBackPressed() 62 | } 63 | binding.n.visibility = View.GONE 64 | } 65 | } 66 | 67 | override fun onClick(view: View) { 68 | val pressedButton = view as MaterialButton 69 | val pressedButtonGender = resources.getResourceEntryName(view.getId()) 70 | if (pressedButtonGender == correctGender && firstClickBoolean) { 71 | updateList(true) 72 | pressedButton.backgroundTintList = 73 | requireContext().getColorStateList(R.color.md_theme_primary) 74 | pressedButton.setTextColor(requireContext().getColorStateList(R.color.md_theme_onPrimary)) 75 | binding.nounText.text = "${pressedButton.text} ${binding.nounText.text}" 76 | binding.nounView.animateJumpAndSlide(requireActivity(), true) 77 | } else if (firstClickBoolean) { 78 | updateList(false) 79 | val correctButton = getCorrectButton(correctGender) 80 | animateButtonDrawable(correctButton) 81 | pressedButton.backgroundTintList = 82 | requireContext().getColorStateList(R.color.md_theme_tertiary) 83 | pressedButton.setTextColor(requireContext().getColorStateList(R.color.md_theme_onTertiary)) 84 | binding.nounText.text = "${correctButton.text} ${binding.nounText.text}" 85 | binding.nounView.animateJumpAndSlide(requireActivity(), false) 86 | } 87 | firstClickBoolean = false 88 | } 89 | 90 | private fun getCorrectButton(correctGender: String?): MaterialButton = when (correctGender) { 91 | "f" -> binding.f 92 | "m" -> binding.m 93 | else -> binding.n 94 | } 95 | 96 | private fun updateList(isCorrect: Boolean) { 97 | wordActivity.allNouns = wordActivity.allNouns 98 | .getUpdatedNounList(currentNoun!!, isCorrect) 99 | .updateIds() 100 | } 101 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/AnimationUtil.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.Context 4 | import android.view.View 5 | import android.view.animation.Animation 6 | import android.view.animation.AnimationUtils 7 | import com.google.android.material.button.MaterialButton 8 | import com.machiav3lli.derdiedas.R 9 | import com.machiav3lli.derdiedas.ui.WordActivity 10 | import kotlinx.coroutines.CoroutineScope 11 | import kotlinx.coroutines.Dispatchers 12 | import kotlinx.coroutines.delay 13 | import kotlinx.coroutines.launch 14 | 15 | object AnimationUtil { 16 | fun animateButtonDrawable(button: MaterialButton) { 17 | val context = button.context 18 | CoroutineScope(Dispatchers.IO).launch { 19 | repeat(4) { 20 | button.backgroundTintList = context.getColorStateList(R.color.md_theme_primary) 21 | button.setTextColor(context.getColorStateList(R.color.md_theme_onPrimary)) 22 | delay(300) 23 | button.backgroundTintList = 24 | context.getColorStateList(R.color.md_theme_secondaryContainer) 25 | button.setTextColor(context.getColorStateList(R.color.md_theme_onSecondaryContainer)) 26 | delay(300) 27 | } 28 | } 29 | } 30 | 31 | fun View.animateJumpAndSlide(context: Context, isCorrectAnswer: Boolean) { 32 | val jumpAnim = AnimationUtils.loadAnimation(context, R.anim.jump_animation) 33 | val waitAnimation = AnimationUtils.loadAnimation(context, R.anim.wait_animation) 34 | waitAnimation.setAnimationListener(object : Animation.AnimationListener { 35 | override fun onAnimationStart(animation: Animation) {} 36 | override fun onAnimationRepeat(animation: Animation) {} 37 | override fun onAnimationEnd(animation: Animation) { 38 | (context as WordActivity).replaceFragment() 39 | } 40 | }) 41 | jumpAnim.setAnimationListener(object : Animation.AnimationListener { 42 | override fun onAnimationStart(animation: Animation) {} 43 | override fun onAnimationRepeat(animation: Animation) {} 44 | override fun onAnimationEnd(animation: Animation) { 45 | (context as WordActivity).replaceFragment() 46 | } 47 | }) 48 | 49 | // if correct answer, we do jump and after that slide the new fragment, 50 | // if wrong, we do flash and after that slide the fragment 51 | if (isCorrectAnswer) { 52 | startAnimation(jumpAnim) 53 | } else { 54 | // we are using this dummy animation which does nothing, to wait for the flashing to end 55 | // and then we replace the fragment (because AnimationDrawable doesn't have a simple 56 | // onFinished listener) - this means the duration in this animation has to be the sum of 57 | // durations in button_animation_correct 58 | startAnimation(waitAnimation) 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/ContextUtil.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.ComponentName 4 | import android.content.Context 5 | import android.content.ContextWrapper 6 | import android.content.Intent 7 | import android.content.res.Configuration 8 | import com.machiav3lli.derdiedas.PREFS_LANG_SYSTEM 9 | import com.machiav3lli.derdiedas.ui.MainActivity 10 | import java.util.* 11 | 12 | fun Context.restartApp() = startActivity( 13 | Intent.makeRestartActivityTask( 14 | ComponentName(this, MainActivity::class.java) 15 | ) 16 | ) 17 | 18 | fun Context.wrap(): ContextWrapper { 19 | val config = setLanguage() 20 | return ContextWrapper(createConfigurationContext(config)) 21 | } 22 | 23 | fun Context.setLanguage(): Configuration { 24 | var setLocalCode = language 25 | if (setLocalCode == PREFS_LANG_SYSTEM) { 26 | setLocalCode = Locale.getDefault().toString() 27 | } 28 | val config = resources.configuration 29 | val sysLocale = config.locales[0] 30 | if (setLocalCode != sysLocale.language || setLocalCode != "${sysLocale.language}-r${sysLocale.country}") { 31 | val newLocale = getLocaleOfCode(setLocalCode) 32 | Locale.setDefault(newLocale) 33 | config.setLocale(newLocale) 34 | } 35 | return config 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/DatabaseUtil.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.Context 4 | import com.machiav3lli.derdiedas.data.Noun 5 | import com.machiav3lli.derdiedas.data.NounDatabase 6 | import java.io.UnsupportedEncodingException 7 | 8 | fun Context.createNounListFromAsset(): MutableList { 9 | var nounsString: String? = null 10 | try { 11 | nounsString = FileUtils.getNounList(this) 12 | } catch (e: UnsupportedEncodingException) { 13 | e.printStackTrace() 14 | } 15 | val nouns = FileUtils.getLines(nounsString!!) 16 | return nouns.map { 17 | val noun = it.split(",").toTypedArray()[0] 18 | val gender = it.split(",").toTypedArray()[1] 19 | Noun(noun, gender, 0) 20 | }.toMutableList() 21 | } 22 | 23 | fun Context.getNounsCount(): Long { 24 | val db = NounDatabase.getInstance(this) 25 | return db.nounDao.count 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/FileUtils.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.Context 4 | import com.machiav3lli.derdiedas.R 5 | import java.io.ByteArrayOutputStream 6 | import java.io.IOException 7 | import java.io.UnsupportedEncodingException 8 | 9 | object FileUtils { 10 | @Throws(UnsupportedEncodingException::class) 11 | fun getNounList(context: Context): String { 12 | val inputStream = context.resources.openRawResource(R.raw.list_nouns) 13 | val result = ByteArrayOutputStream() 14 | val buffer = ByteArray(1024) 15 | var length: Int 16 | try { 17 | while (inputStream.read(buffer).also { length = it } != -1) { 18 | result.write(buffer, 0, length) 19 | } 20 | } catch (e: IOException) { 21 | e.printStackTrace() 22 | } 23 | return result.toString("UTF-8") 24 | } 25 | 26 | fun getLines(string: String): Array = 27 | string.split("\n").toTypedArray() 28 | 29 | @Throws(UnsupportedEncodingException::class) 30 | fun getNounsCount(context: Context) = getLines( 31 | getNounList(context) 32 | ).size.toLong() 33 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/LanguagePref.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import androidx.preference.ListPreference 6 | import com.machiav3lli.derdiedas.BuildConfig 7 | import com.machiav3lli.derdiedas.PREFS_LANG_SYSTEM 8 | import com.machiav3lli.derdiedas.R 9 | 10 | class LanguagePref(context: Context, attrs: AttributeSet?) : ListPreference(context, attrs) { 11 | 12 | init { 13 | loadLangs(context) 14 | } 15 | 16 | private fun loadLangs(context: Context) { 17 | setDefaultValue(PREFS_LANG_SYSTEM) 18 | 19 | val locales: MutableList = ArrayList() 20 | val languagesRaw = BuildConfig.DETECTED_LOCALES.sorted() 21 | for (localeCode in languagesRaw) { 22 | val locale = context.getLocaleOfCode(localeCode) 23 | locales.add("${locale.translate()};$localeCode") 24 | } 25 | 26 | val entries = arrayOfNulls(locales.size + 1) 27 | val entryVals = arrayOfNulls(locales.size + 1) 28 | locales.forEachIndexed { i, locale -> 29 | entries[i + 1] = locale.split(";")[0] 30 | entryVals[i + 1] = locale.split(";")[1] 31 | } 32 | entryVals[0] = PREFS_LANG_SYSTEM 33 | entries[0] = context.resources.getString(R.string.prefs_language_system) 34 | setEntries(entries) 35 | entryValues = entryVals 36 | } 37 | 38 | override fun getSummary(): CharSequence = context.getLocaleOfCode(value).translate() 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/NounUtils.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.Context 4 | import android.content.res.Resources 5 | import com.machiav3lli.derdiedas.data.Noun 6 | 7 | fun Context.getStringByName(name: String) = try { 8 | val resId = resources.getIdentifier(name, "string", packageName) 9 | getString(resId) 10 | } catch (e: Resources.NotFoundException) { 11 | null 12 | } 13 | 14 | fun MutableList.updateIds() = mapIndexed { index, noun -> 15 | noun.withID(index + 1L) 16 | }.toMutableList() -------------------------------------------------------------------------------- /app/src/main/java/com/machiav3lli/derdiedas/utils/PrefsUtil.kt: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas.utils 2 | 3 | import android.content.Context 4 | import com.machiav3lli.derdiedas.PREFS_LANG 5 | import com.machiav3lli.derdiedas.PREFS_LANG_SYSTEM 6 | import com.machiav3lli.derdiedas.PREFS_SHARED 7 | import com.machiav3lli.derdiedas.PREFS_THEME 8 | import java.util.* 9 | 10 | var Context.appTheme: String 11 | get() = getSharedPreferences(PREFS_SHARED, Context.MODE_PRIVATE) 12 | .getString(PREFS_THEME, "") 13 | ?: PREFS_LANG_SYSTEM 14 | set(value) = getSharedPreferences(PREFS_SHARED, Context.MODE_PRIVATE).edit() 15 | .putString(PREFS_THEME, value).apply() 16 | 17 | var Context.language: String 18 | get() = getSharedPreferences(PREFS_SHARED, Context.MODE_PRIVATE) 19 | .getString(PREFS_LANG, PREFS_LANG_SYSTEM) 20 | ?: PREFS_LANG_SYSTEM 21 | set(value) = getSharedPreferences(PREFS_SHARED, Context.MODE_PRIVATE).edit() 22 | .putString(PREFS_LANG, value).apply() 23 | 24 | fun Context.getLocaleOfCode(localeCode: String): Locale = when { 25 | localeCode.isEmpty() -> resources.configuration.locales[0] 26 | localeCode.contains("-r") -> Locale( 27 | localeCode.substring(0, 2), 28 | localeCode.substring(4) 29 | ) 30 | localeCode.contains("_") -> Locale( 31 | localeCode.substring(0, 2), 32 | localeCode.substring(3) 33 | ) 34 | else -> Locale(localeCode) 35 | } 36 | 37 | fun Locale.translate(): String { 38 | val country = getDisplayCountry(this) 39 | val language = getDisplayLanguage(this) 40 | return (language.replaceFirstChar { it.uppercase(Locale.getDefault()) } 41 | + (if (country.isNotEmpty() && country.compareTo(language, true) != 0) 42 | "($country)" else "")) 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/res/anim/jump_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 11 | 12 | 13 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/anim/wait_animation.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 16 | 17 | 23 | 26 | 29 | 30 | 31 | 32 | 36 | 37 | 43 | 46 | 49 | 50 | 51 | 52 | 56 | 57 | 63 | 66 | 69 | 70 | 71 | 72 | 76 | 77 | 83 | 86 | 89 | 90 | 91 | 92 | 96 | 97 | 103 | 106 | 109 | 110 | 111 | 112 | 116 | 117 | 123 | 126 | 129 | 130 | 131 | 132 | 136 | 137 | 143 | 146 | 149 | 150 | 151 | 152 | 156 | 157 | 163 | 166 | 169 | 170 | 171 | 172 | 176 | 177 | 183 | 186 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_foreground_mc.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 18 | 24 | 30 | 36 | 42 | 48 | 54 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_round_arrow_back_32.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_round_help_outline_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 21 | 22 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_stats.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 17 | 18 | 28 | 29 | 40 | 41 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_word.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 17 | 18 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_word.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 18 | 19 | 28 | 29 | 39 | 40 | 41 | 54 | 55 | 62 | 63 | 70 | 71 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/main/res/values-eo/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Metro 4 | Dimanĉo 5 | Foto 6 | Informo 7 | Urbo 8 | Aŭgusto 9 | Januaro 10 | Libro 11 | Lando 12 | Ludo 13 | Miliono 14 | Laboro 15 | Vojo 16 | Komunumo 17 | Mondo 18 | Der 19 | Das 20 | Die 21 | Lingvo 22 | Sistema implicitaĵo 23 | Eŭro 24 | Tago 25 | Viro 26 | Fino 27 | Semajno 28 | Placo 29 | Flanko 30 | Domo 31 | Sabato 32 | Demando 33 | Bildo 34 | Majo 35 | Monato 36 | Grundo 37 | Vendredo 38 | Nomo 39 | Artikolo 40 | Punkto 41 | Minuto 42 | Problemo 43 | Familio 44 | Junio 45 | Marto 46 | Oktobro 47 | Prezidanto 48 | Lernejo 49 | Loko 50 | Mono 51 | Teamo 52 | Aprilo 53 | Registaro 54 | Venko 55 | Trajnisto 56 | Projekto 57 | Mardo 58 | Regiono 59 | Prezo 60 | Februaro 61 | Virino 62 | Homo 63 | Vivo 64 | Temo 65 | Historio 66 | Strato 67 | Asocio 68 | Polico 69 | Septembro 70 | Celo 71 | Lundo 72 | Ĵaŭdo 73 | Partio 74 | Vorto 75 | Programo 76 | Komenco 77 | Grupo 78 | Ekzemplo 79 | Gasto 80 | Horo 81 | Novembro 82 | Filmo 83 | Vendredo 84 | Preĝejo 85 | Julio 86 | Sukceso 87 | Pordego 88 | Nombro 89 | Decembro 90 | Verko 91 | Mano 92 | Lernanto 93 | Plene lernitaj 94 | Statistikoj 95 | Agordoj 96 | Jes 97 | Ne 98 | Etoso 99 | Hela 100 | Malhela 101 | Sistema etoso 102 | 123 / 456 103 | Bundeswirtschaftsministerium 104 | Vi plene lernis ĉiujn substantivojn. Ĉu rekomenci denove\? 105 | Praktiki 106 | Proporcio 107 | Jaro 108 | Horloĝo 109 | Tempo 110 | Infano 111 | Sinjoro 112 | Sezono 113 | Firmao 114 | Verdo 115 | Patro 116 | Alto 117 | Mezo 118 | Ĉefo 119 | Klaso 120 | Morto 121 | Voĉo 122 | Milito 123 | Akvo 124 | Interezo 125 | Interreto 126 | Arto 127 | Kapo 128 | Dolaro 129 | Valoro 130 | Teksto 131 | Somero 132 | Klubo 133 | Teatro 134 | Vico 135 | Koro 136 | Soldato 137 | Proceso 138 | Instruisto 139 | Malsanulejo 140 | Piedo 141 | Vido 142 | Serio 143 | Aero 144 | Arbaro 145 | Profesoro 146 | Insulo 147 | Letero 148 | Energio 149 | Monto 150 | Urbodomo 151 | Kandidato 152 | Vintro 153 | Lago 154 | Kampo 155 | Vetero 156 | Intervjuo 157 | Krizo 158 | Ŝtono 159 | Jardeko 160 | Hundo 161 | Zorgo 162 | Kantisto 163 | Suno 164 | Tradicio 165 | Figuro 166 | Ŝipo 167 | Posttagmezo 168 | Ministro 169 | Vienano 170 | Gastiganto 171 | Nurenbergano 172 | Ĝardeno 173 | Kino 174 | Leganto 175 | Surfaco 176 | Resto 177 | Akcio 178 | Tono 179 | Albumo 180 | Ponto 181 | Provinco 182 | Papero 183 | Versio 184 | Vino 185 | Aŭtobuso 186 | Fajro 187 | Respubliko 188 | Regno 189 | Sonĝo 190 | Parko 191 | Studo 192 | Ĉielo 193 | Reto 194 | Rando 195 | Nordo 196 | Dubo 197 | Kruro 198 | Maŝino 199 | Judo 200 | Danco 201 | Aktiveco 202 | Sudo 203 | Alternativo 204 | Litro 205 | Kategorio 206 | Argumento 207 | Arkitekto 208 | Majencano 209 | Fiŝkaptisto 210 | Oriento 211 | Opero 212 | Kanto 213 | Nordo 214 | Instrumento 215 | Rivero 216 | Dunganto 217 | Temperaturo 218 | Ringo 219 | Demokratio 220 | Vento 221 | Birdo 222 | Ĉevalo 223 | Papo 224 | Spegulo 225 | Kliniko 226 | Generalo 227 | Rusio 228 | Objekto 229 | Testo 230 | Kunlaborado 231 | Metodo 232 | Marko 233 | Fremdulo 234 | Rado 235 | Animo 236 | Forumo 237 | Lernantino 238 | Centimetro 239 | Amikino 240 | Kafo 241 | Uzanto 242 | Laboristo 243 | Aŭtovojo 244 | Hamburgero, Hamburgano 245 | Franco 246 | Socialdemokrato 247 | Scio 248 | Januaro 249 | Ĵazo 250 | Kuirejo 251 | Kapitano 252 | Lito 253 | Ŝablono 254 | Religio 255 | Aspekto 256 | Centra kvartalo 257 | Orelo 258 | Adreso 259 | Turisto 260 | Arĥivo 261 | Teorio 262 | Atmosfero 263 | Manko 264 | Aŭstro 265 | Sango 266 | Dialogo 267 | Skribo 268 | Signalo 269 | Turo 270 | Klimato 271 | Retejo 272 | Kantistino 273 | Biero 274 | Poemo 275 | Varo 276 | Boato 277 | Biografio 278 | Heroo 279 | Kaso 280 | Neĝo 281 | Pluso 282 | Video 283 | Kredito 284 | Statistiko 285 | Princo 286 | Organizanto 287 | Valo 288 | Flugo 289 | Aŭtorino 290 | Dekduo 291 | Rezulto 292 | Edzino 293 | Strategio 294 | Mezuro 295 | Medio 296 | Armeo 297 | Sponsoro 298 | Piano 299 | Fiŝo 300 | Elfo 301 | Fakso 302 | Ombro 303 | Gastejo 304 | Kompromiso 305 | Priskribo 306 | Alkoholo 307 | Floro 308 | Sperto 309 | Krono 310 | Nazo 311 | Dokumento 312 | Analizo 313 | Teniso 314 | Ovo 315 | Kristano 316 | Ĵurio 317 | Hektaro 318 | Kongreso 319 | Buĝeto 320 | Infrastrukturo 321 | Seminario 322 | Ŝuo 323 | Haveno 324 | Muzikalo 325 | Der Die Das 326 | Golfo (ludo) 327 | Helpo 328 | Procento 329 | Ĝenerala sekretario 330 | Angla lingvo 331 | Duonfinalo 332 | Sudo 333 | Medalo 334 | Kristnasko 335 | Sumo 336 | Maro 337 | Oleo 338 | Orkestro 339 | Imperiestro 340 | Federacio 341 | Ligno 342 | Principo 343 | Paro 344 | Scienco 345 | Ŝuldo 346 | Okcidento 347 | Okcidento 348 | Episkopo 349 | Festivalo 350 | Brako 351 | Reformo 352 | Telefono 353 | Ideo 354 | Miliardo 355 | Titolo 356 | Aŭto 357 | Komenco 358 | Politikisto 359 | Futbalo 360 | Filo 361 | Aŭtoro 362 | Muzeo 363 | Universitato 364 | Filino 365 | Plano 366 | Karto 367 | Sporto 368 | Patrino 369 | Informo 370 | Spaco 371 | Linio 372 | Hotelo 373 | Kilometro 374 | Literaturo 375 | Sviso 376 | Matĉo 377 | Artisto 378 | Instituto 379 | Sistemo 380 | Dio 381 | Sekureco 382 | Kurso 383 | Kanto 384 | Centro 385 | Espero 386 | Reĝo 387 | Modelo 388 | Ĝojo 389 | Kantono 390 | Grado 391 | Oriento 392 | Dosiero 393 | Ĉefurbo 394 | Pluvo 395 | Katastrofo 396 | Libereco 397 | Lupo 398 | Universitato 399 | Formulo 400 | Muziko 401 | Diskuto 402 | Turismo 403 | Urbestro 404 | Nokto 405 | Amiko 406 | Okulo 407 | Majstro 408 | Paŝo 409 | Leĝo 410 | Listo 411 | Danĝero 412 | Koncepto 413 | Aŭtuno 414 | Lumo 415 | Respondo 416 | Personeco 417 | Sportisto 418 | Revolucio 419 | Plene lernitaj vortoj / ĉiuj vortoj: 420 | -------------------------------------------------------------------------------- /app/src/main/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Febrero 4 | Premio/precio 5 | Ciudad 6 | Libro 7 | Mano 8 | Región 9 | Manera 10 | Información 11 | Obra/Fabrica 12 | Martes 13 | Proyecto 14 | Diciembre 15 | Número 16 | Programa 17 | Puerta 18 | Palabra 19 | Enero 20 | Entrenador 21 | Partido 22 | Victoria 23 | Jueves 24 | Éxito 25 | Gobierno 26 | Foto 27 | Julio 28 | Iglesia 29 | Lunes 30 | Agosto 31 | Abril 32 | Miércoles 33 | Metro 34 | Meta 35 | Película 36 | Noviembre 37 | Hora 38 | Equipo 39 | Ejemplo 40 | Grupo 41 | Invitado 42 | Equipo 43 | Dinero 44 | Lugar 45 | Escuela 46 | Presidente 47 | Octubre 48 | Marzo 49 | Junio 50 | Familia 51 | Oficina de patentes 52 | Empresa 53 | Problema 54 | Septiembre 55 | Policía 56 | Minuto 57 | Asociación 58 | Punto 59 | Artículo 60 | Nombre 61 | Viernes 62 | Motivo 63 | Mes 64 | Calle 65 | Miembro 66 | Mundo 67 | Historia 68 | Tema 69 | Comunidad 70 | Mayo 71 | Camino 72 | Caso 73 | Cuadro/foto 74 | Trabajo 75 | Parte 76 | Pregunta 77 | Marco 78 | Millón 79 | Vida 80 | Domingo 81 | Sábado 82 | Casa 83 | Lado/página 84 | Juego 85 | Plaza/lugar 86 | Semana 87 | Final 88 | Hombre 89 | Pais 90 | Ciudad 91 | Persona 92 | Mujer 93 | Día 94 | Euro 95 | Niño/a 96 | Tiempo 97 | Porcentaje 98 | Hora 99 | Oscuro 100 | Claro 101 | Tema 102 | Die La 103 | Das El (neutro) 104 | Der El (masc) 105 | Ministerio Federal de Economía y Tecnología 106 | 123 / 456 107 | Califique 108 | Compartir 109 | Estadísticas 110 | Ajustes 111 | Practicar 112 | Palabras completamente aprendidas / Todas las palabras: 113 | Ayuda 114 | Por \"palabras completamente aprendidas\" se entienden los sustantivos que se han respondido correctamente 5 veces seguidas. Se consideran entonces \"totalmente aprendidos\" y no aparecen más en la pantalla de práctica. El objetivo final debe ser \"aprender completamente\" todos los sustantivos. 115 | \n 116 | \nSi se responde correctamente a un sustantivo, pero luego se hace mal antes de conseguirlo 5 veces seguidas, se vuelve a poner a 0 y el proceso de conseguir 5 veces seguidas empieza de nuevo para ese sustantivo. 117 | Completamente aprendido 118 | Der Die Das 119 | Año 120 | No 121 | Si 122 | Ha aprendido todos los sustantivos, ¿quieres empezar de nuevo\? 123 | Tema del sistema 124 | Estación 125 | Indicación 126 | Presidente 127 | Siglo 128 | Ámbito 129 | Resultado 130 | Música 131 | Empleado 132 | Señor 133 | Círculo 134 | Persona 135 | Oportunidad 136 | Inicio 137 | Alumno 138 | Hablar 139 | Carro auto coche 140 | Alcalde 141 | Discusión 142 | Consecuencia 143 | Posibilidad 144 | Jugador 145 | Padre 146 | Huésped, visitante 147 | Ciudadano 148 | Definido por el sistema 149 | Idioma 150 | Decisión 151 | Tarde 152 | Título 153 | Banda 154 | Futuro 155 | Inserto, misión 156 | Empresa 157 | Periódico, diario 158 | Adolescente, joven 159 | Vínculo web, hipervínculo 160 | Lugar, posición 161 | Elección 162 | Habitación 163 | Madre 164 | Desarrollo 165 | -------------------------------------------------------------------------------- /app/src/main/res/values-hi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Der Die Das 4 | पूरी तरह से सीखा 5 | मदद 6 | सेटिंग्स 7 | आँकड़े 8 | शेयर 9 | \"पूरी तरह से सीखे गए शब्द\" का अर्थ उन संज्ञाओं से है जिनका लगातार 5 बार सही उत्तर दिया गया है। तब उन्हें \"पूरी तरह से सीखा हुआ\" माना जाता है और वे अब अभ्यास स्क्रीन में दिखाई नहीं देते हैं। अंतिम लक्ष्य सभी संज्ञाओं को \"पूरी तरह से सीखना\" होना चाहिए। 10 | \n 11 | \nयदि किसी संज्ञा का सही उत्तर दिया जाता है, लेकिन फिर गलत तरीके से लगातार 5 बार प्राप्त करने से पहले, उसे वापस 0 पर रीसेट कर दिया जाता है और उस संज्ञा के लिए एक पंक्ति में 5 बार आने की प्रक्रिया फिर से शुरू होती है। 12 | पूरी तरह से सीखे गए शब्द / सभी शब्द: 13 | अभ्यास 14 | मूल्यांकन 15 | 123 / 456 16 | सिस्टम की थीम 17 | भाषा 18 | -------------------------------------------------------------------------------- /app/src/main/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Causa 4 | Caso 5 | Processo 6 | Concetto 7 | Pericolo 8 | Vigili del fuoco 9 | Organizzazione 10 | Proposta/Suggerimento 11 | Autorità 12 | Amore 13 | Comparazione 14 | Registrazione 15 | Paura/Ansia 16 | Linea 17 | Fan 18 | Cosa 19 | Suolo 20 | Soldato 21 | Castello/Serratura 22 | Sicurezza 23 | Informazione 24 | Dio 25 | Sistema 26 | Inizio/Decollo 27 | Termine/Nozione 28 | Villaggio 29 | Collaborazione 30 | Pressione 31 | Cuore 32 | Significato 33 | Unione 34 | Sport 35 | Lista 36 | Veicolo 37 | Soluzione 38 | Rappresentante/Procuratore 39 | Medico 40 | Metà 41 | Avversario/Rivale 42 | Ragazzo 43 | Sostegno 44 | Berlinese 45 | Compleanno 46 | Legge 47 | Esperienza 48 | Contratto 49 | Partecipante 50 | Cultura 51 | Lingua 52 | Edificio 53 | Negozio 54 | Piano 55 | Editore 56 | Popolazione 57 | Artista 58 | Contatto 59 | Club 60 | Confine 61 | Azione 62 | Tribunale/Piatto 63 | Bagno 64 | Estate 65 | Testo 66 | Figlia 67 | Fonte 68 | Frase 69 | Svizzero 70 | Palcoscenico 71 | Lotta/Combattimento 72 | Cliente 73 | Scheda/Carta 74 | Valore 75 | Economia 76 | Uomo 77 | Paese 78 | Città 79 | Umano 80 | Donna 81 | Giorno 82 | Euro 83 | Bambino 84 | Tempo 85 | Percentuale 86 | Ora 87 | Anno 88 | No 89 | 90 | Hai imparato tutti i sostantivi, vuoi ricominciare\? 91 | Tema del sistema 92 | Scuro 93 | Chiaro 94 | Tema 95 | Die 96 | Das 97 | Der 98 | Ministero federale dell\'economia 99 | 123 / 456 100 | Valuta 101 | Condividi 102 | Statistiche 103 | Impostazioni 104 | Pratica 105 | Parole completamente imparate / Tutte le parole: 106 | Aiuto 107 | «Parole completamente imparate» si riferisce ai sostantivi a cui si è risposto correttamente 5 volte di seguito. Sono quindi considerati «completamente imparati» e non appaiono più nella schermata di pratica. L\'obiettivo finale dovrebbe essere quello di «imparare completamente» tutti i sostantivi. 108 | \n 109 | \nSe un sostantivo viene risposto correttamente, ma poi in modo errato prima di raggiungere 5 volte di fila, viene riportato a 0 e il processo di ottenere 5 volte di fila ricomincia per quel sostantivo. 110 | Completamente imparato 111 | Der Die Das 112 | Concerto 113 | Museo 114 | Treno 115 | Vittima 116 | Pubblico 117 | Situazione 118 | Disposizione 119 | Rapporto 120 | Costruzione/Struttura 121 | Senso 122 | Forza 123 | Ragazza 124 | Dollaro 125 | Università 126 | Spettatore 127 | Idea 128 | Miliardo 129 | Internet 130 | Telaio/Bordo 131 | Testa 132 | Arte 133 | Guerra 134 | Acqua 135 | Interesse 136 | Diritto 137 | Letteratura 138 | Morte 139 | Direzione 140 | Voce 141 | Chilometro 142 | Servizio/Impresa 143 | Classe 144 | Politico 145 | Occhio 146 | Capo 147 | Compito 148 | Misura 149 | Figlio 150 | Forma/Figura 151 | Mercato 152 | Autore 153 | Società 154 | Evento 155 | Calcio 156 | Notte 157 | Altezza 158 | Amico 159 | Esposizione/Mostra 160 | Contributo 161 | Ruolo 162 | Offerta 163 | Inizio 164 | Telefono 165 | Aiuto 166 | Fine settimana 167 | Pezzo 168 | Cittadino 169 | Visitatore 170 | Padre 171 | Sviluppo/Progresso 172 | Madre 173 | Spazio/Stanza 174 | Collegamento web 175 | Adolescente 176 | Giornale 177 | Scelta/Elezione 178 | Posizione 179 | Decisione 180 | Giocatore 181 | Possibilità 182 | Conseguenza 183 | Discussione 184 | Sindaco 185 | Impresa 186 | Futuro 187 | Sera 188 | Titolo 189 | Auto 190 | Discussione 191 | Stagione 192 | Presidentessa 193 | Risultato 194 | Musica 195 | Dipendente/Collega 196 | Signore 197 | Persona 198 | Inizio 199 | Febbraio 200 | Prezzo 201 | Stato 202 | Libro 203 | Mano 204 | Regione 205 | Maniera/Modo 206 | Informazione 207 | Fabbrica/Opera 208 | Martedì 209 | Progetto 210 | Dicembre 211 | Numero 212 | Programma 213 | Cancello 214 | Parola 215 | Gennaio 216 | Allenatore 217 | Partito (pol.) 218 | Vittoria 219 | Giovedì 220 | Successo 221 | Governo 222 | Foto 223 | Luglio 224 | Chiesa 225 | Lunedì 226 | Agosto 227 | Aprile 228 | Mercoledì 229 | Metro 230 | Scopo/Obiettivo 231 | Film 232 | Novembre 233 | Ora 234 | Squadra 235 | Esempio 236 | Gruppo 237 | Ospite 238 | Squadra 239 | Soldi 240 | Luogo 241 | Scuola 242 | Presidente 243 | Ottobre 244 | Marzo 245 | Giugno 246 | Famiglia 247 | Ufficio brevetti 248 | Azienda 249 | Problema 250 | Settembre 251 | Polizia 252 | Minuto 253 | Associazione 254 | Punto 255 | Articolo 256 | Nome 257 | Venerdì 258 | Mese 259 | Via/Strada 260 | Membro 261 | Mondo 262 | Storia 263 | Argomento 264 | Comune/Comunità 265 | Maggio 266 | Percorso 267 | Immagine 268 | Lavoro 269 | Elemento/Parte 270 | Domanda 271 | Mark 272 | Milione 273 | Vita 274 | Domenica 275 | Sabato 276 | Casa 277 | Lato 278 | Gioco 279 | Spazio/Piazza 280 | Settimana 281 | Fine 282 | -------------------------------------------------------------------------------- /app/src/main/res/values-ko/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 인생의 1년 4 | 5 | 확률 6 | 점수 7 | 공간/장소 8 | 어두운 9 | 주간 10 | 여자 11 | 인간 12 | 연습 13 | 시스템 테마 14 | 완전히 학습된 단어들 / 모든 단어들: 15 | Die 16 | 연방 경제부 17 | \"완전히 학습된 단어\"란 연속 5번 정답을 맞추면 됩니다. 그러면 \"완전히 학습된\" 것으로 간주되어 더 이상 연습 화면에 표시되지 않습니다. 궁극적인 목표는 모든 명사를 \"완전히 학습\"하는 것입니다. 18 | \n 19 | \n명사로 된 정답을 맞추었다가 연속 5회를 달성하기 전에 틀리면 다시 0으로 재설정되고 다시 연속 5회를 맞추는 과정이 시작됩니다. 20 | 연도 (시간) 21 | 도움받기 22 | Das 23 | 인생 24 | 시간 25 | 아이 26 | Euro 27 | 완전히 학습함 28 | 29 | 123 / 456 30 | 시계 31 | 테마 32 | 아니오 33 | 도시 34 | Der 35 | 일자 36 | 학습 상황 37 | 남자 38 | 백만 39 | 40 | 나라 41 | 일요일 42 | 게임 43 | 모든 명사를 완전히 학습했습니다. 다시 시작하시겠습니까\? 44 | 마크 (통화) 45 | 언어 46 | 설정 47 | 48 | Der Die Das 49 | 이전 연도 (시간) 50 | 토요일 51 | 공유하기 52 | 종료 53 | 연도 (특정 연도의 그룹) 54 | 시스템 기본값 55 | -------------------------------------------------------------------------------- /app/src/main/res/values-nb-rNO/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Prosess 4 | Konsept 5 | Fare 6 | Organisasjon 7 | Sammenligning 8 | Registrering 9 | Linje 10 | Ting 11 | Sikkerhet 12 | Informasjon 13 | Gud 14 | System 15 | Trykk 16 | Hjerte 17 | Mening 18 | Sport 19 | Kollega 20 | Liste 21 | Kjøretøy 22 | Løsning 23 | Doktor 24 | Gutt 25 | Støtte 26 | Geburtsdag 27 | Lov 28 | Erfaring 29 | Kontrakt 30 | Deltager 31 | Kultur 32 | Språk 33 | Fest 34 | Bygning 35 | Territorium 36 | Steg 37 | Teater 38 | Dyr 39 | Plan 40 | Befolkning 41 | Artist 42 | Kontakt 43 | Grense 44 | Sommer 45 | Tekst 46 | Datter 47 | Kunde 48 | Kort 49 | Verdi 50 | Økonomi 51 | Konsert 52 | Museum 53 | Tog 54 | Situasjon 55 | Styrke 56 | Jente 57 | Dollar 58 | Universitet 59 | Tilskuer 60 | Idé 61 | Milliard 62 | Internett 63 | Hode 64 | Kunst 65 | Krig 66 | Vann 67 | Litteratur 68 | Død 69 | Stemme 70 | Kilometer 71 | Ytelse 72 | Politiker 73 | Øye 74 | Sønn 75 | Marked 76 | Fotball 77 | Natt 78 | Høyde 79 | Venn 80 | Utstilling 81 | Bidrag 82 | Rolle 83 | Telefon 84 | Hjelp 85 | Grønn 86 | Innbygger 87 | Far 88 | Mor 89 | Avis 90 | Posisjon 91 | Avgjørelse 92 | Spiller 93 | Mulighet 94 | Konsekvens 95 | Diskusjon 96 | Bil 97 | Sesong 98 | Resultat 99 | Musikk 100 | Ansatt/kollega 101 | Herr. 102 | Person 103 | Sjanse 104 | Start 105 | Februar 106 | Pris 107 | Bok 108 | Hand 109 | Informasjon 110 | Tirsdag 111 | Prosjekt 112 | Desember 113 | Nummer 114 | Program 115 | Ord 116 | Januar 117 | Parti (pol.) 118 | Seier 119 | Torsdag 120 | Vellykket 121 | Bilde 122 | Juli 123 | Kirke 124 | Mandag 125 | August 126 | April 127 | Onsdag 128 | Meter 129 | Film 130 | November 131 | Time 132 | Eksempel 133 | Gruppe 134 | Gjest 135 | Lag 136 | Penger 137 | President 138 | Oktober 139 | Mars 140 | Juni 141 | Familie 142 | Patentkontor 143 | Problem 144 | September 145 | Politi 146 | Minutt 147 | Navn 148 | Fredag 149 | Måned 150 | Medlem 151 | Verden 152 | Emne 153 | Gemenskap 154 | Mai 155 | Sti 156 | Arbeid 157 | Element 158 | Spørsmål 159 | Million 160 | Liv 161 | Søndag 162 | Lørdag 163 | Hus 164 | Side 165 | Spill 166 | Uke 167 | Slutt 168 | Mann 169 | Land 170 | By 171 | Menneske 172 | Kvinne 173 | Dag 174 | Euro 175 | Barn 176 | Tid 177 | Prosent 178 | Time 179 | År 180 | Systemforvalg 181 | Mørk 182 | Lys 183 | Drakt 184 | 123 / 456 185 | Vurder 186 | Del 187 | Statistikk 188 | Innstillinger 189 | Øvelse 190 | Hjelp 191 | Der Die Das 192 | Helt innlært 193 | «Helt innlærte ord» er substantiver som har blitt besvart riktig fem ganger på rad. De anses «helt innlært» og vil ikke lenger vises på øvelsesskjermen. Det ultimate målet er å ha alle substantiver helt innlært. 194 | \n 195 | \nHvis et substantiv besvares riktig, men så feil før det tuktes fem ganger på rad, tilbakestilles det til null og prosessen starter på ny. 196 | Helt innlærte ord / alle ord: 197 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | #111111 5 | 6 | #22E541 7 | #003907 8 | #00530F 9 | #72FF71 10 | #8ACEFF 11 | #00344E 12 | #004B6F 13 | #C9E6FF 14 | #FFB3AC 15 | #670309 16 | #881E1D 17 | #FFDAD6 18 | #FFB4AB 19 | #93000A 20 | #690005 21 | #FFDAD6 22 | #001F2A 23 | #BFE9FF 24 | #001F2A 25 | #BFE9FF 26 | #424940 27 | #C2C8BD 28 | #8C9388 29 | #001F2A 30 | #BFE9FF 31 | #006E17 32 | #000000 33 | #22E541 34 | #424940 35 | #000000 36 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 37 | 38 | 43 | 44 | 47 | 48 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-notnight/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 37 | 38 | 43 | 44 | 47 | 48 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/values-ru/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Полностью изученные 4 | Помощь 5 | Полностью изученные слова / Все слова: 6 | Практика 7 | Настройки 8 | Оценить 9 | 123 / 456 10 | Федеральное министерство экономики 11 | Der (м.р.) 12 | Das (с.р.) 13 | Die (ж.р.) 14 | Тема 15 | Светлая 16 | Темная 17 | Системная тема 18 | Полностью выучили все существительные, хотите начать сначала\? 19 | Да 20 | Нет 21 | Процент 22 | Время 23 | Ребенок 24 | Евро 25 | День 26 | Женщина 27 | Мужчина 28 | Конец 29 | Неделя 30 | Сторона 31 | Дом 32 | Суббота 33 | Воскресенье 34 | Жизнь 35 | Миллион 36 | Оценка 37 | Вопрос 38 | Предмет 39 | Работа 40 | Картинка 41 | Случай 42 | Тропа 43 | Имя 44 | Статья 45 | Точка 46 | Объединение 47 | Минута 48 | Полиция 49 | Сентябрь 50 | Проблема 51 | Фирма 52 | Патентное бюро 53 | Семья 54 | Июнь 55 | Президент 56 | Школа 57 | Место 58 | Деньги 59 | Группа 60 | Пример 61 | Команда 62 | Час 63 | Ноябрь 64 | Фильм 65 | Понедельник 66 | Церковь 67 | Июль 68 | Фотография 69 | Правительство 70 | Успех 71 | Четверг 72 | Победа 73 | Вечеринка 74 | Тренер 75 | Январь 76 | Слово 77 | Ворота 78 | Программа 79 | Общество 80 | Автор 81 | Величина 82 | Учреждение 83 | Директор 84 | Глаз 85 | Политик 86 | Класс / Курс 87 | Предприятие 88 | Производительность 89 | Километр 90 | Голос 91 | Война 92 | Голова 93 | Рамка 94 | Интернет 95 | Миллиард 96 | Идея 97 | Зритель 98 | Руководство 99 | Критика 100 | Университет 101 | Доллар 102 | Локация 103 | Девушка 104 | Сила 105 | Смысл 106 | Конструкция 107 | Доклад 108 | Расположение 109 | Ситуация 110 | Публика 111 | Жертва 112 | Поезд 113 | Музей 114 | Цена 115 | Карточка 116 | Клиент 117 | Битва 118 | Сцена 119 | Швейцарский 120 | Предложение 121 | Источник 122 | Дочь 123 | Текст 124 | Лето 125 | Блюдо 126 | Действие 127 | Контакт 128 | Издание 129 | Театр 130 | Der Die Das 131 | Шаг 132 | Территория 133 | Статистика 134 | История 135 | Участник 136 | «Полностью выученные слова» означают существительные, которые были отмечены правильно 5 раз подряд. После этого они считаются «полностью выученными» и больше не отображаются на странице практики. Конечная цель должна состоять в том, чтобы «полностью выучить» все существительные. 137 | \n 138 | \nЕсли существительное отмечено правильно, но затем была допущена ошибка до достижения 5 раз подряд, оно сбрасывается обратно на 0 и для этого существительного снова начинается процесс изучения 5 раз подряд. 139 | Поделиться 140 | Литература 141 | Человек 142 | Страна 143 | Год 144 | Часы 145 | Май 146 | Тема 147 | Город 148 | Место 149 | Игра 150 | Общество 151 | Мир 152 | Месяц 153 | Улица 154 | Причина 155 | Пятница 156 | Вода 157 | Октябрь 158 | Сын 159 | Март 160 | Апрель 161 | Август 162 | Событие 163 | Середина 164 | Взгляд 165 | Команда 166 | Гость 167 | Цель 168 | Среда 169 | Высота 170 | Ночь 171 | Рынок 172 | Форма 173 | Задание 174 | Метр 175 | Футбол 176 | Направление 177 | Искусство 178 | Право (направление) 179 | Интерес 180 | Смерть 181 | Концерт 182 | Экономика 183 | Граница 184 | Клуб 185 | Население 186 | Животное 187 | Ванна 188 | Художник 189 | План 190 | Союз 191 | Здание 192 | Мнение 193 | Вечеринка 194 | Магазин 195 | -------------------------------------------------------------------------------- /app/src/main/res/values-tr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Yardım 4 | Tam öğrenilen kelimeler / Tüm kelimeler: 5 | Der Die Das 6 | Tamamen Öğrenilmiş 7 | İstatistikler 8 | Paylaş 9 | Tema 10 | Açık 11 | Koyu 12 | Tüm isimleri tamamen öğrendiniz, baştan başlamak ister misiniz\? 13 | Evet 14 | Hayır 15 | Yıl 16 | Zaman 17 | Ülke 18 | Erkek 19 | Son 20 | Hafta 21 | Boşluk/Yer 22 | Oyun 23 | Taraf 24 | Ev 25 | Cumartesi 26 | Pazar 27 | Ayarlar 28 | Alıştırma 29 | Değerlendir 30 | Sistem teması 31 | 123 / 456 32 | Dil 33 | Sistem varsayılanı 34 | Saat 35 | Çocuk 36 | Yüzde 37 | Euro 38 | Gün 39 | Kadın 40 | İnsan 41 | Şehir 42 | Hayat 43 | Milyon 44 | -------------------------------------------------------------------------------- /app/src/main/res/values-zh-rCN/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 已学会 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | @string/theme_light 5 | @string/theme_dark 6 | @string/theme_system 7 | 8 | 9 | 10 | light 11 | dark 12 | system 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #EEEEEE 5 | 6 | #006E17 7 | #FFFFFF 8 | #72FF71 9 | #002203 10 | #006491 11 | #FFFFFF 12 | #C9E6FF 13 | #001E2F 14 | #A83632 15 | #FFFFFF 16 | #FFDAD6 17 | #410003 18 | #BA1A1A 19 | #FFDAD6 20 | #FFFFFF 21 | #410002 22 | #FAFCFF 23 | #001F2A 24 | #FAFCFF 25 | #001F2A 26 | #DEE5D8 27 | #424940 28 | #73796F 29 | #E1F4FF 30 | #003547 31 | #22E541 32 | #000000 33 | #006E17 34 | #C2C8BD 35 | #000000 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #C9E6FF 4 | -------------------------------------------------------------------------------- /app/src/main/res/xml/preferences.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 12 | 13 | 18 | -------------------------------------------------------------------------------- /app/src/test/java/com/machiav3lli/derdiedas/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.machiav3lli.derdiedas; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /badge_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/badge_github.png -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | google() 5 | } 6 | dependencies { 7 | classpath("com.android.tools.build:gradle:8.1.2") 8 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | mavenCentral() 15 | google() 16 | } 17 | } 18 | 19 | tasks.register("clean", Delete::class) { 20 | delete(rootProject.buildDir) 21 | } 22 | -------------------------------------------------------------------------------- /fastlane/metadata/android/de/short_description.txt: -------------------------------------------------------------------------------- 1 | Geschlechter der deutschen Substantive lernen -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/1100.txt: -------------------------------------------------------------------------------- 1 | **DerDieDas 1.1.0** 2 | * Added: new App Icon 3 | * Added: Dark Theme comatible with System Theme 4 | * Updated: cleaner UI 5 | * and some other tweaks 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/1101.txt: -------------------------------------------------------------------------------- 1 | **DerDieDas 1.1.1** 2 | * Fixed: crashing settings 3 | * Added: back button 4 | * Fixed: applying theme on resume 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/1102.txt: -------------------------------------------------------------------------------- 1 | **DerDieDas 1.1.2** 2 | * Fixed: theme not being applied in Main 3 | * Migrated: to private preferences 4 | * Some UI optimizations 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/1201.txt: -------------------------------------------------------------------------------- 1 | * Updated: More mainstream colors 2 | * Fixed: Crash on click stats info 3 | * Fixed: Button's text size not fitting in all screens 4 | * Some code and UI cleaned up 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2000.txt: -------------------------------------------------------------------------------- 1 | WARNING: Progress will be reset 2 | * Update to a RoomDatabase 3 | * Add translations (300 for now) 4 | * Migrate to Kotlin 5 | * Performance improvment 6 | * A lot of small fixes 7 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2001.txt: -------------------------------------------------------------------------------- 1 | * Add: WordViewModel. 2 | * Add: Choice to restart when all the words are fully learned. 3 | * Fix: Crashing on practice & stats 4 | * Update: Convert DatabaseUtil to file and abstract creating noun list out of the into it 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2002.txt: -------------------------------------------------------------------------------- 1 | * Update: Start again instead of returning back to the main menu 2 | * Fix: Clearing the nouns list on double clicking a choice 3 | * Add: Words' translation till 500th 4 | * Add: Translations to French, Norwegian, Spanish & Italian 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2003.txt: -------------------------------------------------------------------------------- 1 | * Update: Target- and CompiledSDK 31 2 | * Add: Words' translation till 1000th 3 | * Update: Dependencies & Gradle 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2100.txt: -------------------------------------------------------------------------------- 1 | * Add: 200 words' translations (total 1200) 2 | * Add: Languages setting 3 | * Update translations: Polish, Ukrainian, Russian, French, Norwegian 4 | * Update: Target- and CompileSDK 32 5 | + other small fixes 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2101.txt: -------------------------------------------------------------------------------- 1 | Add: Show right article beside word after clicking 2 | Update TargetSDK 33 3 | 40+ translation contributions 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/2200.txt: -------------------------------------------------------------------------------- 1 | Add: Translations 1201→1300 2 | Update: Material 3 design 3 | Update CompileSDK 34 4 | 10+ translations 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | Learn German nouns genders in an easy way. This app has almost 10,000 German nouns. The app takes care of repeating the nouns which you haven’t yet learned properly. If you master them, they are removed and the practice progress towards harder words. 2 | 3 | Words are ordered by everyday use frequency, which means that the most common words will appear at the start, but through progress less and less known nouns will appear, for which it’s presumably harder to know the correct gender. 4 | 5 | Features: 6 | 7 | * choose a light or dark theme 8 | * visual feedback with green for correct answers and red for wrong answers will help you learn more efficiently 9 | * track your progress 10 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Android app for learning German nouns genders. 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | android.useAndroidX=true 2 | org.gradle.daemon=true 3 | org.gradle.configureondemand=true 4 | android.defaults.buildfeatures.buildconfig=true 5 | android.nonTransitiveRClass=false 6 | android.nonFinalResIds=false 7 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machiav3lli/DerDieDas/58ebedf8066e87f05c099625d60c2939581ae165/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Oct 13 23:25:26 CEST 2023 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------