74 |
75 | suspend fun getByParam(
76 | param: String, value: P
77 | ) = getByParam(SimpleSQLiteQuery("$baseWhereQuery $param='$value'"))
78 |
79 | suspend fun getByParams(
80 | paramPair: Pair,
81 | vararg paramPairs: Pair
82 | ): List {
83 | val params = listOf(paramPair, *paramPairs)
84 | val condition = buildString {
85 | params.forEachIndexed { index, pair ->
86 | append("${pair.first}='${pair.second}'")
87 | if (index != params.lastIndex) append(" and ")
88 | }
89 | }
90 | return getByParam(SimpleSQLiteQuery("$baseWhereQuery $condition"))
91 | }
92 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/db/dao/DAOs.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl/Owl.app.main
3 | * DAOs.kt Copyrighted by Yamin Siahmargooei at 2022/12/27
4 | * DAOs.kt Last modified at 2022/12/27
5 | * This file is part of Owl/Owl.app.main.
6 | * Copyright (C) 2022 Yamin Siahmargooei
7 | *
8 | * Owl/Owl.app.main is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * Owl/Owl.app.main is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with Owl. If not, see .
20 | */
21 |
22 | package io.github.yamin8000.owl.db.dao
23 |
24 | import androidx.room.Dao
25 | import io.github.yamin8000.owl.db.entity.DefinitionEntity
26 | import io.github.yamin8000.owl.db.entity.WordEntity
27 |
28 | object DAOs {
29 | @Dao
30 | abstract class DefinitionDao : BaseDao("DefinitionEntity")
31 |
32 | @Dao
33 | abstract class WordDao : BaseDao("WordEntity")
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/db/entity/DefinitionEntity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl/Owl.app.main
3 | * DefinitionEntity.kt Copyrighted by Yamin Siahmargooei at 2022/12/27
4 | * DefinitionEntity.kt Last modified at 2022/12/27
5 | * This file is part of Owl/Owl.app.main.
6 | * Copyright (C) 2022 Yamin Siahmargooei
7 | *
8 | * Owl/Owl.app.main is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * Owl/Owl.app.main is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with Owl. If not, see .
20 | */
21 |
22 | package io.github.yamin8000.owl.db.entity
23 |
24 | import androidx.room.ColumnInfo
25 | import androidx.room.Entity
26 | import androidx.room.ForeignKey
27 | import androidx.room.PrimaryKey
28 |
29 | @Entity(
30 | foreignKeys = [
31 | ForeignKey(
32 | entity = WordEntity::class,
33 | parentColumns = ["id"],
34 | childColumns = ["wordId"],
35 | onDelete = ForeignKey.RESTRICT
36 | )
37 | ]
38 | )
39 | data class DefinitionEntity(
40 | @ColumnInfo(name = "wordId", index = true)
41 | val wordId: Long,
42 | val type: String?,
43 | val definition: String,
44 | val example: String?,
45 | val imageUrl: String?,
46 | val emoji: String?,
47 | @PrimaryKey(autoGenerate = true)
48 | val id: Long = 0
49 | )
50 |
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/db/entity/WordEntity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl/Owl.app.main
3 | * WordEntity.kt Copyrighted by Yamin Siahmargooei at 2022/12/27
4 | * WordEntity.kt Last modified at 2022/12/27
5 | * This file is part of Owl/Owl.app.main.
6 | * Copyright (C) 2022 Yamin Siahmargooei
7 | *
8 | * Owl/Owl.app.main is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * Owl/Owl.app.main is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with Owl. If not, see .
20 | */
21 |
22 | package io.github.yamin8000.owl.db.entity
23 |
24 | import androidx.room.Entity
25 | import androidx.room.PrimaryKey
26 |
27 | @Entity
28 | data class WordEntity(
29 | val word: String,
30 | val pronunciation: String? = null,
31 | @PrimaryKey(autoGenerate = true)
32 | val id: Long = 0
33 | )
34 |
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/model/Definition.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Definition.kt Created by Yamin Siahmargooei at 2022/1/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.model
22 |
23 | import android.os.Parcelable
24 | import androidx.compose.runtime.Immutable
25 | import com.squareup.moshi.Json
26 | import io.github.yamin8000.owl.util.Constants.IMAGE_URL
27 | import kotlinx.parcelize.Parcelize
28 |
29 | @Immutable
30 | @Parcelize
31 | data class Definition(
32 | val type: String?,
33 | val definition: String,
34 | val example: String?,
35 | @field:Json(name = IMAGE_URL) val imageUrl: String?,
36 | val emoji: String?
37 | ) : Parcelable
38 |
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/model/RandomWord.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * RandomWord.kt Created by Yamin Siahmargooei at 2022/8/20
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.model
22 |
23 | data class RandomWord(val word: String)
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/model/Word.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Word.kt Created by Yamin Siahmargooei at 2022/1/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.model
22 |
23 | import android.os.Parcelable
24 | import kotlinx.parcelize.Parcelize
25 |
26 | @Parcelize
27 | data class Word(
28 | val word: String,
29 | val pronunciation: String?,
30 | val definitions: List
31 | ) : Parcelable
32 |
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/network/APIs.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * APIs.kt Created by Yamin Siahmargooei at 2022/1/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.network
22 |
23 | import io.github.yamin8000.owl.BuildConfig
24 | import io.github.yamin8000.owl.model.RandomWord
25 | import io.github.yamin8000.owl.model.Word
26 | import retrofit2.http.GET
27 | import retrofit2.http.Headers
28 | import retrofit2.http.Path
29 |
30 | object APIs {
31 |
32 | interface OwlBotWordAPI {
33 |
34 | @Headers(BuildConfig.OWLBOT_TOKEN)
35 | @GET("dictionary/{word}")
36 | suspend fun searchWord(@Path("word") word: String): Word?
37 | }
38 |
39 | interface NinjaAPI {
40 |
41 | @Suppress("SpellCheckingInspection")
42 | @Headers(BuildConfig.API_NINJA_KEY)
43 | @GET("randomword")
44 | suspend fun getRandomWord(): RandomWord
45 | }
46 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/network/Web.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Web.kt Created by Yamin Siahmargooei at 2022/1/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.network
22 |
23 | import retrofit2.Retrofit
24 | import retrofit2.converter.moshi.MoshiConverterFactory
25 |
26 | @Suppress("SameParameterValue")
27 | object Web {
28 |
29 | private const val baseUrl = "https://owlbot.info/api/v4/"
30 | private const val ninjaApiBaseUrl = "https://api.api-ninjas.com/v1/"
31 |
32 | val retrofit: Retrofit by lazy(LazyThreadSafetyMode.NONE) { createRetrofit() }
33 |
34 | val ninjaApiRetrofit: Retrofit by lazy(LazyThreadSafetyMode.NONE) { createNinjaApiRetrofit() }
35 |
36 | private fun createNinjaApiRetrofit(): Retrofit {
37 | return createCustomUrlRetrofit(ninjaApiBaseUrl)
38 | }
39 |
40 | private fun createCustomUrlRetrofit(baseUrl: String): Retrofit {
41 | return Retrofit.Builder()
42 | .baseUrl(baseUrl)
43 | .addConverterFactory(MoshiConverterFactory.create())
44 | .build()
45 | }
46 |
47 | private fun createRetrofit(): Retrofit {
48 | return Retrofit.Builder()
49 | .baseUrl(baseUrl)
50 | .addConverterFactory(MoshiConverterFactory.create())
51 | .build()
52 | }
53 |
54 | /**
55 | * get service of given api/interface
56 | *
57 | * @param T type/class/interface of api
58 | * @return service for that api
59 | */
60 | inline fun Retrofit.getAPI(): T = this.create(T::class.java)
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/composable/Animations.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Animations.kt Created by Yamin Siahmargooei at 2022/11/8
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.composable
22 |
23 | import androidx.compose.animation.core.RepeatMode
24 | import androidx.compose.animation.core.VectorConverter
25 | import androidx.compose.animation.core.animate
26 | import androidx.compose.animation.core.infiniteRepeatable
27 | import androidx.compose.animation.core.tween
28 | import androidx.compose.foundation.layout.size
29 | import androidx.compose.material3.Icon
30 | import androidx.compose.material3.MaterialTheme
31 | import androidx.compose.runtime.Composable
32 | import androidx.compose.runtime.LaunchedEffect
33 | import androidx.compose.runtime.getValue
34 | import androidx.compose.runtime.mutableStateOf
35 | import androidx.compose.runtime.remember
36 | import androidx.compose.runtime.setValue
37 | import androidx.compose.ui.Modifier
38 | import androidx.compose.ui.res.painterResource
39 | import androidx.compose.ui.res.stringResource
40 | import androidx.compose.ui.unit.Dp
41 | import androidx.compose.ui.unit.dp
42 | import io.github.yamin8000.owl.R
43 |
44 | @Composable
45 | fun AnimatedAppIcon(
46 | isAnimating: Boolean = true
47 | ) {
48 | var size by remember { mutableStateOf(0.dp) }
49 |
50 | LaunchedEffect(Unit) {
51 | while (isAnimating) {
52 | animate(
53 | typeConverter = Dp.VectorConverter,
54 | initialValue = 64.dp,
55 | targetValue = 56.dp,
56 | animationSpec = infiniteRepeatable(
57 | animation = tween(1000),
58 | repeatMode = RepeatMode.Reverse
59 | ),
60 | block = { value, _ -> size = value }
61 | )
62 | }
63 | }
64 |
65 | Icon(
66 | painter = painterResource(R.drawable.ic_launcher_foreground),
67 | contentDescription = stringResource(R.string.app_name),
68 | tint = MaterialTheme.colorScheme.onSurface,
69 | modifier = Modifier.size(size)
70 | )
71 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/composable/Cards.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Cards.kt Created by Yamin Siahmargooei at 2022/8/24
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.composable
22 |
23 | import androidx.compose.foundation.layout.Arrangement
24 | import androidx.compose.foundation.layout.Column
25 | import androidx.compose.foundation.layout.ColumnScope
26 | import androidx.compose.foundation.layout.fillMaxWidth
27 | import androidx.compose.foundation.layout.padding
28 | import androidx.compose.material3.Card
29 | import androidx.compose.material3.MaterialTheme
30 | import androidx.compose.material3.Text
31 | import androidx.compose.runtime.Composable
32 | import androidx.compose.runtime.getValue
33 | import androidx.compose.runtime.mutableStateOf
34 | import androidx.compose.runtime.remember
35 | import androidx.compose.runtime.setValue
36 | import androidx.compose.ui.Alignment
37 | import androidx.compose.ui.Modifier
38 | import androidx.compose.ui.hapticfeedback.HapticFeedbackType
39 | import androidx.compose.ui.platform.LocalHapticFeedback
40 | import androidx.compose.ui.text.style.TextAlign
41 | import androidx.compose.ui.unit.dp
42 | import androidx.compose.ui.unit.sp
43 | import io.github.yamin8000.owl.ui.theme.DefaultCutShape
44 |
45 | @Composable
46 | fun SettingsItemCard(
47 | modifier: Modifier = Modifier,
48 | columnModifier: Modifier = Modifier,
49 | title: String,
50 | content: @Composable ColumnScope.() -> Unit
51 | ) {
52 | Column(
53 | verticalArrangement = Arrangement.spacedBy(4.dp),
54 | horizontalAlignment = Alignment.Start,
55 | content = {
56 | PersianText(
57 | text = title,
58 | fontSize = 18.sp,
59 | color = MaterialTheme.colorScheme.primary
60 | )
61 | Card(
62 | modifier = modifier,
63 | shape = DefaultCutShape,
64 | content = {
65 | Column(
66 | modifier = columnModifier.padding(16.dp),
67 | verticalArrangement = Arrangement.spacedBy(8.dp),
68 | horizontalAlignment = Alignment.CenterHorizontally,
69 | content = { content() }
70 | )
71 | }
72 | )
73 | },
74 | )
75 | }
76 |
77 | @Composable
78 | fun RemovableCard(
79 | item: String,
80 | onClick: () -> Unit,
81 | onLongClick: () -> Unit
82 | ) {
83 | var isMenuExpanded by remember { mutableStateOf(false) }
84 | val haptic = LocalHapticFeedback.current
85 | Card(
86 | shape = DefaultCutShape,
87 | content = {
88 | Ripple(
89 | modifier = Modifier.padding(8.dp),
90 | onClick = onClick,
91 | onLongClick = { isMenuExpanded = true },
92 | content = {
93 | Text(
94 | text = item,
95 | textAlign = TextAlign.Center,
96 | modifier = Modifier
97 | .padding(16.dp)
98 | .fillMaxWidth()
99 | )
100 | }
101 | )
102 | DeleteMenu(
103 | expanded = isMenuExpanded,
104 | onDismiss = { isMenuExpanded = false },
105 | onDelete = {
106 | isMenuExpanded = false
107 | haptic.performHapticFeedback(HapticFeedbackType.LongPress)
108 | onLongClick()
109 | }
110 | )
111 | }
112 | )
113 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/navigation/Nav.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * NavigationConstants.kt Created by Yamin Siahmargooei at 2022/8/21
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.navigation
22 |
23 | object Nav {
24 | object Routes {
25 | data object Home
26 | data object History
27 | data object Settings
28 | data object About
29 | data object Favourites
30 | }
31 |
32 | object Arguments {
33 | data object Search
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/theme/Color.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Color.kt Created by Yamin Siahmargooei at 2022/6/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.theme
22 |
23 | import androidx.compose.ui.graphics.Color
24 |
25 | val md_theme_light_primary = Color(0xFFBB0055)
26 | val md_theme_light_onPrimary = Color(0xFFFFFFFF)
27 | val md_theme_light_primaryContainer = Color(0xFFFFC4CE)
28 | val md_theme_light_onPrimaryContainer = Color(0xFF3F0018)
29 | val md_theme_light_secondary = Color(0xFF75565C)
30 | val md_theme_light_onSecondary = Color(0xFFFFFFFF)
31 | val md_theme_light_secondaryContainer = Color(0xFFFFD9DF)
32 | val md_theme_light_onSecondaryContainer = Color(0xFF2B151A)
33 | val md_theme_light_tertiary = Color(0xFF7A5733)
34 | val md_theme_light_onTertiary = Color(0xFFFFFFFF)
35 | val md_theme_light_tertiaryContainer = Color(0xFFFFDCBD)
36 | val md_theme_light_onTertiaryContainer = Color(0xFF2C1600)
37 | val md_theme_light_error = Color(0xFFBA1A1A)
38 | val md_theme_light_errorContainer = Color(0xFFFFDAD6)
39 | val md_theme_light_onError = Color(0xFFFFFFFF)
40 | val md_theme_light_onErrorContainer = Color(0xFF410002)
41 | val md_theme_light_background = Color(0xFFFBE9E7)
42 | val md_theme_light_onBackground = Color(0xFF201A1B)
43 | val md_theme_light_surface = Color(0xFFFBE9E7)
44 | val md_theme_light_onSurface = Color(0xFF201A1B)
45 | val md_theme_light_surfaceVariant = Color(0xFFF3DDE0)
46 | val md_theme_light_onSurfaceVariant = Color(0xFF524346)
47 | val md_theme_light_outline = Color(0xFF847375)
48 | val md_theme_light_inverseOnSurface = Color(0xFFFAEEEF)
49 | val md_theme_light_inverseSurface = Color(0xFF352F30)
50 | val md_theme_light_inversePrimary = Color(0xFFFFB1C2)
51 | //val md_theme_light_shadow = Color(0xFF000000)
52 | val md_theme_light_surfaceTint = Color(0xFFBB0055)
53 | //val md_theme_light_surfaceTintColor = Color(0xFFBB0055)
54 |
55 | val md_theme_dark_primary = Color(0xFFFFB1C2)
56 | val md_theme_dark_onPrimary = Color(0xFF66002B)
57 | val md_theme_dark_primaryContainer = Color(0xFF8F0040)
58 | val md_theme_dark_onPrimaryContainer = Color(0xFFFFD9DF)
59 | val md_theme_dark_secondary = Color(0xFFE4BDC4)
60 | val md_theme_dark_onSecondary = Color(0xFF43292F)
61 | val md_theme_dark_secondaryContainer = Color(0xFF5B3F45)
62 | val md_theme_dark_onSecondaryContainer = Color(0xFFFFD9DF)
63 | val md_theme_dark_tertiary = Color(0xFFECBE91)
64 | val md_theme_dark_onTertiary = Color(0xFF462A09)
65 | val md_theme_dark_tertiaryContainer = Color(0xFF60401E)
66 | val md_theme_dark_onTertiaryContainer = Color(0xFFFFDCBD)
67 | val md_theme_dark_error = Color(0xFFFFB4AB)
68 | val md_theme_dark_errorContainer = Color(0xFF93000A)
69 | val md_theme_dark_onError = Color(0xFF690005)
70 | val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
71 | val md_theme_dark_background = Color(0xFF201A1B)
72 | val md_theme_dark_onBackground = Color(0xFFECE0E0)
73 | val md_theme_dark_surface = Color(0xFF201A1B)
74 | val md_theme_dark_onSurface = Color(0xFFECE0E0)
75 | val md_theme_dark_surfaceVariant = Color(0xFF524346)
76 | val md_theme_dark_onSurfaceVariant = Color(0xFFD6C2C4)
77 | val md_theme_dark_outline = Color(0xFF9E8C8F)
78 | val md_theme_dark_inverseOnSurface = Color(0xFF201A1B)
79 | val md_theme_dark_inverseSurface = Color(0xFFECE0E0)
80 | val md_theme_dark_inversePrimary = Color(0xFFBB0055)
81 | //val md_theme_dark_shadow = Color(0xFF000000)
82 | val md_theme_dark_surfaceTint = Color(0xFFFFB1C2)
83 | //val md_theme_dark_surfaceTintColor = Color(0xFFFFB1C2)
84 |
85 |
86 | //val seed = Color(0xFFBB0055)
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/theme/Shape.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl/Owl.app.main
3 | * Shape.kt Copyrighted by Yamin Siahmargooei at 2023/1/7
4 | * Shape.kt Last modified at 2023/1/7
5 | * This file is part of Owl/Owl.app.main.
6 | * Copyright (C) 2023 Yamin Siahmargooei
7 | *
8 | * Owl/Owl.app.main is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * Owl/Owl.app.main is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with Owl. If not, see .
20 | */
21 |
22 | package io.github.yamin8000.owl.ui.theme
23 |
24 | import androidx.compose.foundation.shape.CutCornerShape
25 | import androidx.compose.ui.unit.dp
26 |
27 | val DefaultCutShape = CutCornerShape(15.dp)
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/theme/Theme.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Theme.kt Created by Yamin Siahmargooei at 2022/6/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.theme
22 |
23 | import android.app.Activity
24 | import android.os.Build
25 | import androidx.compose.foundation.isSystemInDarkTheme
26 | import androidx.compose.material3.*
27 | import androidx.compose.runtime.Composable
28 | import androidx.compose.runtime.SideEffect
29 | import androidx.compose.ui.graphics.toArgb
30 | import androidx.compose.ui.platform.LocalContext
31 | import androidx.compose.ui.platform.LocalView
32 | import androidx.core.view.WindowCompat
33 |
34 | private val LightColors = lightColorScheme(
35 | primary = md_theme_light_primary,
36 | onPrimary = md_theme_light_onPrimary,
37 | primaryContainer = md_theme_light_primaryContainer,
38 | onPrimaryContainer = md_theme_light_onPrimaryContainer,
39 | inversePrimary = md_theme_light_inversePrimary,
40 | secondary = md_theme_light_secondary,
41 | onSecondary = md_theme_light_onSecondary,
42 | secondaryContainer = md_theme_light_secondaryContainer,
43 | onSecondaryContainer = md_theme_light_onSecondaryContainer,
44 | tertiary = md_theme_light_tertiary,
45 | onTertiary = md_theme_light_onTertiary,
46 | tertiaryContainer = md_theme_light_tertiaryContainer,
47 | onTertiaryContainer = md_theme_light_onTertiaryContainer,
48 | background = md_theme_light_background,
49 | onBackground = md_theme_light_onBackground,
50 | surface = md_theme_light_surface,
51 | onSurface = md_theme_light_onSurface,
52 | surfaceVariant = md_theme_light_surfaceVariant,
53 | onSurfaceVariant = md_theme_light_onSurfaceVariant,
54 | surfaceTint = md_theme_light_surfaceTint,
55 | inverseSurface = md_theme_light_inverseSurface,
56 | inverseOnSurface = md_theme_light_inverseOnSurface,
57 | error = md_theme_light_error,
58 | onError = md_theme_light_onError,
59 | errorContainer = md_theme_light_errorContainer,
60 | onErrorContainer = md_theme_light_onErrorContainer,
61 | outline = md_theme_light_outline,
62 | //surfaceTintColor = md_theme_light_surfaceTintColor,
63 | )
64 |
65 |
66 | private val DarkColors = darkColorScheme(
67 | primary = md_theme_dark_primary,
68 | onPrimary = md_theme_dark_onPrimary,
69 | primaryContainer = md_theme_dark_primaryContainer,
70 | onPrimaryContainer = md_theme_dark_onPrimaryContainer,
71 | secondary = md_theme_dark_secondary,
72 | onSecondary = md_theme_dark_onSecondary,
73 | secondaryContainer = md_theme_dark_secondaryContainer,
74 | onSecondaryContainer = md_theme_dark_onSecondaryContainer,
75 | tertiary = md_theme_dark_tertiary,
76 | onTertiary = md_theme_dark_onTertiary,
77 | tertiaryContainer = md_theme_dark_tertiaryContainer,
78 | onTertiaryContainer = md_theme_dark_onTertiaryContainer,
79 | error = md_theme_dark_error,
80 | errorContainer = md_theme_dark_errorContainer,
81 | onError = md_theme_dark_onError,
82 | onErrorContainer = md_theme_dark_onErrorContainer,
83 | background = md_theme_dark_background,
84 | onBackground = md_theme_dark_onBackground,
85 | surface = md_theme_dark_surface,
86 | onSurface = md_theme_dark_onSurface,
87 | surfaceVariant = md_theme_dark_surfaceVariant,
88 | onSurfaceVariant = md_theme_dark_onSurfaceVariant,
89 | outline = md_theme_dark_outline,
90 | inverseOnSurface = md_theme_dark_inverseOnSurface,
91 | inverseSurface = md_theme_dark_inverseSurface,
92 | inversePrimary = md_theme_dark_inversePrimary,
93 | surfaceTint = md_theme_dark_surfaceTint,
94 | //surfaceTintColor = md_theme_dark_surfaceTintColor,
95 | )
96 |
97 | @Composable
98 | fun OwlTheme(
99 | isDarkTheme: Boolean = isSystemInDarkTheme(),
100 | isPreviewing: Boolean = false,
101 | isDynamicColor: Boolean,
102 | content: @Composable () -> Unit
103 | ) {
104 | val isDynamicColorReadyDevice = isDynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
105 |
106 | val colors = when {
107 | isDynamicColorReadyDevice && isDarkTheme -> dynamicDarkColorScheme(LocalContext.current)
108 | isDynamicColorReadyDevice && !isDarkTheme -> dynamicLightColorScheme(LocalContext.current)
109 | isDarkTheme -> DarkColors
110 | else -> LightColors
111 | }
112 |
113 | if (!isPreviewing) {
114 | val activity = LocalView.current.context as Activity
115 | SideEffect {
116 | activity.window.statusBarColor = colors.surface.toArgb()
117 | activity.window.navigationBarColor = colors.surface.toArgb()
118 | val wic = WindowCompat.getInsetsController(activity.window, activity.window.decorView)
119 | wic.isAppearanceLightStatusBars = !isDarkTheme
120 | wic.isAppearanceLightNavigationBars = !isDarkTheme
121 | }
122 | }
123 |
124 | MaterialTheme(
125 | colorScheme = colors,
126 | typography = AppTypography,
127 | content = content
128 | )
129 | }
130 |
131 | @Suppress("unused")
132 | @Composable
133 | fun PreviewTheme(
134 | isDarkTheme: Boolean = isSystemInDarkTheme(),
135 | content: @Composable () -> Unit
136 | ) {
137 | OwlTheme(
138 | isDarkTheme = isDarkTheme,
139 | isPreviewing = true,
140 | isDynamicColor = false,
141 | content = content
142 | )
143 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/theme/Type.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Type.kt Created by Yamin Siahmargooei at 2022/6/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.theme
22 |
23 | import androidx.compose.material3.Typography
24 | import androidx.compose.ui.text.TextStyle
25 | import androidx.compose.ui.text.font.Font
26 | import androidx.compose.ui.text.font.FontFamily
27 | import androidx.compose.ui.text.font.FontWeight
28 | import androidx.compose.ui.unit.sp
29 | import io.github.yamin8000.owl.R
30 |
31 | val Samim = FontFamily(Font(R.font.samimbold))
32 |
33 | val Roboto = FontFamily.Default
34 |
35 | val AppTypography = Typography(
36 | labelLarge = TextStyle(
37 | fontFamily = Roboto,
38 | fontWeight = FontWeight.Medium,
39 | letterSpacing = 0.10000000149011612.sp,
40 | lineHeight = 20.sp,
41 | fontSize = 14.sp
42 | ),
43 | labelMedium = TextStyle(
44 | fontFamily = Roboto,
45 | fontWeight = FontWeight.Medium,
46 | letterSpacing = 0.5.sp,
47 | lineHeight = 16.sp,
48 | fontSize = 12.sp
49 | ),
50 | labelSmall = TextStyle(
51 | fontFamily = Roboto,
52 | fontWeight = FontWeight.Medium,
53 | letterSpacing = 0.5.sp,
54 | lineHeight = 16.sp,
55 | fontSize = 11.sp
56 | ),
57 | bodyLarge = TextStyle(
58 | fontFamily = Roboto,
59 | fontWeight = FontWeight.W400,
60 | letterSpacing = 0.5.sp,
61 | lineHeight = 24.sp,
62 | fontSize = 16.sp
63 | ),
64 | bodyMedium = TextStyle(
65 | fontFamily = Roboto,
66 | fontWeight = FontWeight.W400,
67 | letterSpacing = 0.25.sp,
68 | lineHeight = 20.sp,
69 | fontSize = 14.sp
70 | ),
71 | bodySmall = TextStyle(
72 | fontFamily = Roboto,
73 | fontWeight = FontWeight.W400,
74 | letterSpacing = 0.4000000059604645.sp,
75 | lineHeight = 16.sp,
76 | fontSize = 12.sp
77 | ),
78 | headlineLarge = TextStyle(
79 | fontFamily = Roboto,
80 | fontWeight = FontWeight.W400,
81 | letterSpacing = 0.sp,
82 | lineHeight = 40.sp,
83 | fontSize = 32.sp
84 | ),
85 | headlineMedium = TextStyle(
86 | fontFamily = Roboto,
87 | fontWeight = FontWeight.W400,
88 | letterSpacing = 0.sp,
89 | lineHeight = 36.sp,
90 | fontSize = 28.sp
91 | ),
92 | headlineSmall = TextStyle(
93 | fontFamily = Roboto,
94 | fontWeight = FontWeight.W400,
95 | letterSpacing = 0.sp,
96 | lineHeight = 32.sp,
97 | fontSize = 24.sp
98 | ),
99 | displayLarge = TextStyle(
100 | fontFamily = Roboto,
101 | fontWeight = FontWeight.W400,
102 | letterSpacing = (-0.25).sp,
103 | lineHeight = 64.sp,
104 | fontSize = 57.sp
105 | ),
106 | displayMedium = TextStyle(
107 | fontFamily = Roboto,
108 | fontWeight = FontWeight.W400,
109 | letterSpacing = 0.sp,
110 | lineHeight = 52.sp,
111 | fontSize = 45.sp
112 | ),
113 | displaySmall = TextStyle(
114 | fontFamily = Roboto,
115 | fontWeight = FontWeight.W400,
116 | letterSpacing = 0.sp,
117 | lineHeight = 44.sp,
118 | fontSize = 36.sp
119 | ),
120 | titleLarge = TextStyle(
121 | fontFamily = Roboto,
122 | fontWeight = FontWeight.W400,
123 | letterSpacing = 0.sp,
124 | lineHeight = 28.sp,
125 | fontSize = 22.sp
126 | ),
127 | titleMedium = TextStyle(
128 | fontFamily = Roboto,
129 | fontWeight = FontWeight.Medium,
130 | letterSpacing = 0.15000000596046448.sp,
131 | lineHeight = 24.sp,
132 | fontSize = 16.sp
133 | ),
134 | titleSmall = TextStyle(
135 | fontFamily = Roboto,
136 | fontWeight = FontWeight.Medium,
137 | letterSpacing = 0.10000000149011612.sp,
138 | lineHeight = 20.sp,
139 | fontSize = 14.sp
140 | ),
141 | )
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/ui/util/DynamicColorPalette.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * DynamicColorPalette.kt Created by Yamin Siahmargooei at 2022/9/26
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.ui.util
22 |
23 | import android.content.Context
24 | import androidx.collection.LruCache
25 | import androidx.compose.animation.animateColorAsState
26 | import androidx.compose.animation.core.Spring
27 | import androidx.compose.animation.core.spring
28 | import androidx.compose.material3.MaterialTheme
29 | import androidx.compose.runtime.*
30 | import androidx.compose.ui.graphics.Color
31 | import androidx.compose.ui.platform.LocalContext
32 | import androidx.core.graphics.drawable.toBitmap
33 | import androidx.palette.graphics.Palette
34 | import coil.imageLoader
35 | import coil.request.ImageRequest
36 | import coil.request.SuccessResult
37 | import coil.size.Scale
38 | import kotlinx.coroutines.Dispatchers
39 | import kotlinx.coroutines.withContext
40 |
41 | @Composable
42 | fun rememberDominantColorState(
43 | context: Context = LocalContext.current,
44 | defaultColor: Color = MaterialTheme.colorScheme.surfaceVariant,
45 | defaultOnColor: Color = MaterialTheme.colorScheme.onSurfaceVariant,
46 | cacheSize: Int = 12,
47 | isColorValid: (Color) -> Boolean = { true }
48 | ): DominantColorState = remember {
49 | DominantColorState(context, defaultColor, defaultOnColor, cacheSize, isColorValid)
50 | }
51 |
52 | /**
53 | * A composable which allows dynamic theming of the [androidx.compose.material.Colors.primary]
54 | * color from an image.
55 | */
56 | @Composable
57 | fun DynamicThemePrimaryColorsFromImage(
58 | dominantColorState: DominantColorState = rememberDominantColorState(),
59 | content: @Composable () -> Unit
60 | ) {
61 | val colors = MaterialTheme.colorScheme.copy(
62 | primary = animateColorAsState(
63 | dominantColorState.color,
64 | spring(stiffness = Spring.StiffnessLow)
65 | ).value,
66 | onPrimary = animateColorAsState(
67 | dominantColorState.onColor,
68 | spring(stiffness = Spring.StiffnessLow)
69 | ).value
70 | )
71 | MaterialTheme(colorScheme = colors, content = content)
72 | }
73 |
74 | /**
75 | * A class which stores and caches the result of any calculated dominant colors
76 | * from images.
77 | *
78 | * @param context Android context
79 | * @param defaultColor The default color, which will be used if [calculateDominantColor] fails to
80 | * calculate a dominant color
81 | * @param defaultOnColor The default foreground 'on color' for [defaultColor].
82 | * @param cacheSize The size of the [LruCache] used to store recent results. Pass `0` to
83 | * disable the cache.
84 | * @param isColorValid A lambda which allows filtering of the calculated image colors.
85 | */
86 | @Stable
87 | class DominantColorState(
88 | private val context: Context,
89 | private val defaultColor: Color,
90 | private val defaultOnColor: Color,
91 | cacheSize: Int = 12,
92 | private val isColorValid: (Color) -> Boolean = { true }
93 | ) {
94 | var color by mutableStateOf(defaultColor)
95 | private set
96 | var onColor by mutableStateOf(defaultOnColor)
97 | private set
98 |
99 | private val cache = when {
100 | cacheSize > 0 -> LruCache(cacheSize)
101 | else -> null
102 | }
103 |
104 | suspend fun updateColorsFromImageUrl(url: String) {
105 | val result = calculateDominantColor(url)
106 | color = result?.color ?: defaultColor
107 | onColor = result?.onColor ?: defaultOnColor
108 | }
109 |
110 | private suspend fun calculateDominantColor(url: String): DominantColors? {
111 | val cached = cache?.get(url)
112 | if (cached != null) {
113 | // If we already have the result cached, return early now...
114 | return cached
115 | }
116 |
117 | // Otherwise we calculate the swatches in the image, and return the first valid color
118 | return calculateSwatchesInImage(context, url)
119 | .filter { swatch ->
120 | val lightness = swatch.hsl[2]
121 | val saturation = swatch.hsl[1]
122 | lightness > .1f && lightness <= .9f && saturation >= .1f
123 | }
124 | // First we want to sort the list by the color's population
125 | .sortedByDescending { swatch -> swatch.population }
126 | // Then we want to find the first valid color
127 | .firstOrNull { swatch -> isColorValid(Color(swatch.rgb)) }
128 | // If we found a valid swatch, wrap it in a [DominantColors]
129 | ?.let { swatch ->
130 | DominantColors(
131 | color = Color(swatch.rgb),
132 | onColor = Color(swatch.bodyTextColor).copy(alpha = 1f)
133 | )
134 | }
135 | // Cache the resulting [DominantColors]
136 | ?.also { result -> cache?.put(url, result) }
137 | }
138 |
139 | /**
140 | * Reset the color values to [defaultColor].
141 | */
142 | fun reset() {
143 | color = defaultColor
144 | onColor = defaultOnColor
145 | }
146 | }
147 |
148 | @Immutable
149 | private data class DominantColors(val color: Color, val onColor: Color)
150 |
151 | /**
152 | * Fetches the given [imageUrl] with Coil, then uses [Palette] to calculate the dominant color.
153 | */
154 | private suspend fun calculateSwatchesInImage(
155 | context: Context,
156 | imageUrl: String
157 | ): List {
158 | val request = ImageRequest.Builder(context)
159 | .data(imageUrl)
160 | // We scale the image to cover 128px x 128px (i.e. min dimension == 128px)
161 | .size(128).scale(Scale.FILL)
162 | // Disable hardware bitmaps, since Palette uses Bitmap.getPixels()
163 | .allowHardware(false)
164 | // Set a custom memory cache key to avoid overwriting the displayed image in the cache
165 | .memoryCacheKey("$imageUrl.palette")
166 | .build()
167 |
168 | val bitmap = when (val result = context.imageLoader.execute(request)) {
169 | is SuccessResult -> result.drawable.toBitmap()
170 | else -> null
171 | }
172 |
173 | return bitmap?.let {
174 | withContext(Dispatchers.Default) {
175 | val palette = Palette.Builder(bitmap)
176 | // Disable any bitmap resizing in Palette. We've already loaded an appropriately
177 | // sized bitmap through Coil
178 | .resizeBitmapArea(0)
179 | // Clear any built-in filters. We want the unfiltered dominant color
180 | .clearFilters()
181 | // We reduce the maximum color count down to 8
182 | .maximumColorCount(8)
183 | .generate()
184 |
185 | palette.swatches
186 | }
187 | } ?: emptyList()
188 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/AutoCompleteHelper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * AutoCompleteHelper.kt Created by Yamin Siahmargooei at 2022/10/22
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.util
22 |
23 | import android.content.Context
24 | import android.content.res.Resources.NotFoundException
25 | import io.github.yamin8000.owl.R
26 | import io.github.yamin8000.owl.util.Constants.DEFAULT_N_GRAM_SIZE
27 | import io.github.yamin8000.owl.util.Constants.NOT_WORD_CHARS_REGEX
28 | import io.github.yamin8000.owl.util.Constants.db
29 | import kotlinx.coroutines.CoroutineScope
30 | import kotlinx.coroutines.launch
31 | import kotlin.math.abs
32 | import kotlin.math.ceil
33 | import kotlin.math.roundToInt
34 |
35 | class AutoCompleteHelper(
36 | private val context: Context,
37 | coroutineScope: CoroutineScope,
38 | userData: List = listOf()
39 | ) {
40 | private var data = setOf()
41 |
42 | init {
43 | data = getBasic2000Data().plus(userData).toSet()
44 | coroutineScope.launch { data = data.plus(getOldSearchData()) }
45 | }
46 |
47 | private fun getBasic2000Data() = try {
48 | context.resources.openRawResource(R.raw.basic2000)
49 | .bufferedReader()
50 | .use { it.readText() }
51 | .split(',')
52 | .map { it.replace(NOT_WORD_CHARS_REGEX, "") }
53 | } catch (e: NotFoundException) {
54 | listOf()
55 | }
56 |
57 | suspend fun suggestTermsForSearch(
58 | searchTerm: String
59 | ): List {
60 | data = data.plus(getOldSearchData())
61 |
62 | val term = searchTerm.lowercase().replace(NOT_WORD_CHARS_REGEX, "")
63 | val nGramSize = nGramSizeProvider(term)
64 | if (data.contains(term)) return listOf(term)
65 | val searchTermGrams = term.windowed(nGramSize)
66 | val suggestions = buildSet {
67 | searchTermGrams.forEach { gram ->
68 | addAll(data.filter { word -> word.contains(gram) })
69 | }
70 | }
71 | return sortSuggestions(suggestions, term)
72 | }
73 |
74 | private fun sortSuggestions(
75 | suggestions: Set,
76 | searchTerm: String
77 | ): List {
78 | val nGramSize = nGramSizeProvider(searchTerm)
79 | if (suggestions.isNotEmpty() && suggestions.size > 1) {
80 | val searchTermGrams = searchTerm.windowed(nGramSize)
81 | val rankedSuggestions = buildList {
82 | suggestions.forEach { suggestion ->
83 | val rank = suggestion.windowed(nGramSize)
84 | .intersect(searchTermGrams.toSet())
85 | .size
86 | add(rank to suggestion)
87 | }
88 | }
89 | return rankedSuggestions.asSequence()
90 | .sortedBy { abs(it.second.length - searchTerm.length) }
91 | .sortedByDescending {
92 | it.second.startsWith(searchTerm.take(nGramSize)) ||
93 | it.second.endsWith(searchTerm.takeLast(nGramSize))
94 | }
95 | .sortedByDescending { it.first }
96 | .map { it.second }
97 | .toList()
98 | } else return suggestions.toList()
99 | }
100 |
101 | private fun nGramSizeProvider(
102 | searchTerm: String
103 | ): Int {
104 | return if (searchTerm.length > DEFAULT_N_GRAM_SIZE) {
105 | val size = ceil(searchTerm.length.toFloat() / DEFAULT_N_GRAM_SIZE).roundToInt()
106 | if (size < DEFAULT_N_GRAM_SIZE) DEFAULT_N_GRAM_SIZE
107 | else size
108 | } else DEFAULT_N_GRAM_SIZE
109 | }
110 |
111 | private suspend fun getOldSearchData() = db.wordDao().getAll().map { it.word }
112 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/Constants.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Constants.kt Created by Yamin Siahmargooei at 2022/1/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.util
22 |
23 | import io.github.yamin8000.owl.db.AppDatabase
24 |
25 | object Constants {
26 | lateinit var db: AppDatabase
27 | const val LOG_TAG = "<==>"
28 |
29 | const val IMAGE_URL = "image_url"
30 | const val THEME = "theme"
31 | const val TTS_LANG = "tts_lang"
32 | const val IS_VIBRATING = "is_vibrating"
33 |
34 | const val DEFAULT_N_GRAM_SIZE = 3
35 |
36 | val NOT_WORD_CHARS_REGEX = Regex("\\W+")
37 |
38 | const val INTERNET_CHECK_DELAY = 3000L
39 | val DNS_SERVERS = listOf(
40 | "8.8.8.8",
41 | "8.8.4.4",
42 | "1.1.1.1",
43 | "1.0.0.1",
44 | "185.51.200.2",
45 | "178.22.122.100",
46 | "10.202.10.202",
47 | "10.202.10.102"
48 | )
49 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/DataStoreHelper.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * DataStoreHelper.kt Created by Yamin Siahmargooei at 2022/9/20
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.util
22 |
23 | import androidx.datastore.core.DataStore
24 | import androidx.datastore.preferences.core.*
25 | import kotlinx.coroutines.flow.firstOrNull
26 | import kotlinx.coroutines.flow.map
27 |
28 | @Suppress("unused")
29 | class DataStoreHelper(
30 | private val datastore: DataStore
31 | ) {
32 |
33 | suspend fun getString(
34 | key: String
35 | ) = datastore.data.map {
36 | it[stringPreferencesKey(key)]
37 | }.firstOrNull()
38 |
39 | suspend fun setString(
40 | key: String,
41 | value: String
42 | ) {
43 | datastore.edit {
44 | it[stringPreferencesKey(key)] = value
45 | }
46 | }
47 |
48 | suspend fun getInt(
49 | key: String
50 | ) = datastore.data.map {
51 | it[intPreferencesKey(key)]
52 | }.firstOrNull()
53 |
54 | suspend fun setInt(
55 | key: String,
56 | value: Int
57 | ) {
58 | datastore.edit {
59 | it[intPreferencesKey(key)] = value
60 | }
61 | }
62 |
63 | suspend fun getBool(
64 | key: String
65 | ) = datastore.data.map {
66 | it[booleanPreferencesKey(key)]
67 | }.firstOrNull()
68 |
69 | suspend fun setBool(
70 | key: String,
71 | value: Boolean
72 | ) {
73 | datastore.edit {
74 | it[booleanPreferencesKey(key)] = value
75 | }
76 | }
77 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/RecomposeHighlighter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * RecomposeHighlighter.kt Created by Yamin Siahmargooei at 2022/10/15
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.util
22 |
23 | import androidx.compose.runtime.LaunchedEffect
24 | import androidx.compose.runtime.Stable
25 | import androidx.compose.runtime.mutableStateOf
26 | import androidx.compose.runtime.remember
27 | import androidx.compose.ui.Modifier
28 | import androidx.compose.ui.composed
29 | import androidx.compose.ui.draw.drawWithCache
30 | import androidx.compose.ui.geometry.Offset
31 | import androidx.compose.ui.geometry.Size
32 | import androidx.compose.ui.graphics.Color
33 | import androidx.compose.ui.graphics.SolidColor
34 | import androidx.compose.ui.graphics.drawscope.Fill
35 | import androidx.compose.ui.graphics.drawscope.Stroke
36 | import androidx.compose.ui.graphics.lerp
37 | import androidx.compose.ui.platform.debugInspectorInfo
38 | import androidx.compose.ui.unit.dp
39 | import kotlinx.coroutines.delay
40 | import kotlin.math.min
41 |
42 | /**
43 | * A [Modifier] that draws a border around elements that are recomposing. The border increases in
44 | * size and interpolates from red to green as more recompositions occur before a timeout.
45 | */
46 | @Stable
47 | fun Modifier.recomposeHighlighter(): Modifier = this.then(recomposeModifier)
48 |
49 | // Use a single instance + @Stable to ensure that recompositions can enable skipping optimizations
50 | // Modifier.composed will still remember unique data per call site.
51 | private val recomposeModifier =
52 | Modifier.composed(inspectorInfo = debugInspectorInfo { name = "recomposeHighlighter" }) {
53 | // The total number of compositions that have occurred. We're not using a State<> here be
54 | // able to read/write the value without invalidating (which would cause infinite
55 | // recomposition).
56 | val totalCompositions = remember { arrayOf(0L) }
57 | totalCompositions[0]++
58 |
59 | // The value of totalCompositions at the last timeout.
60 | val totalCompositionsAtLastTimeout = remember { mutableStateOf(0L) }
61 |
62 | // Start the timeout, and reset everytime there's a recomposition. (Using totalCompositions
63 | // as the key is really just to cause the timer to restart every composition).
64 | LaunchedEffect(totalCompositions[0]) {
65 | delay(3000)
66 | totalCompositionsAtLastTimeout.value = totalCompositions[0]
67 | }
68 |
69 | Modifier.drawWithCache {
70 | onDrawWithContent {
71 | // Draw actual content.
72 | drawContent()
73 |
74 | // Below is to draw the highlight, if necessary. A lot of the logic is copied from
75 | // Modifier.border
76 | val numCompositionsSinceTimeout =
77 | totalCompositions[0] - totalCompositionsAtLastTimeout.value
78 |
79 | val hasValidBorderParams = size.minDimension > 0f
80 | if (!hasValidBorderParams || numCompositionsSinceTimeout <= 0) {
81 | return@onDrawWithContent
82 | }
83 |
84 | val (color, strokeWidthPx) =
85 | when (numCompositionsSinceTimeout) {
86 | // We need at least one composition to draw, so draw the smallest border
87 | // color in blue.
88 | 1L -> Color.Blue to 1f
89 | // 2 compositions is _probably_ okay.
90 | 2L -> Color.Green to 2.dp.toPx()
91 | // 3 or more compositions before timeout may indicate an issue. lerp the
92 | // color from yellow to red, and continually increase the border size.
93 | else -> {
94 | lerp(
95 | Color.Yellow.copy(alpha = 0.8f),
96 | Color.Red.copy(alpha = 0.5f),
97 | min(1f, (numCompositionsSinceTimeout - 1).toFloat() / 100f)
98 | ) to numCompositionsSinceTimeout.toInt().dp.toPx()
99 | }
100 | }
101 |
102 | val halfStroke = strokeWidthPx / 2
103 | val topLeft = Offset(halfStroke, halfStroke)
104 | val borderSize = Size(size.width - strokeWidthPx, size.height - strokeWidthPx)
105 |
106 | val fillArea = (strokeWidthPx * 2) > size.minDimension
107 | val rectTopLeft = if (fillArea) Offset.Zero else topLeft
108 | val size = if (fillArea) size else borderSize
109 | val style = if (fillArea) Fill else Stroke(strokeWidthPx)
110 |
111 | drawRect(
112 | brush = SolidColor(color),
113 | topLeft = rectTopLeft,
114 | size = size,
115 | style = style
116 | )
117 | }
118 | }
119 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/TTS.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * TTS.kt Created by Yamin Siahmargooei at 2022/10/12
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.util
22 |
23 | import android.content.Context
24 | import android.speech.tts.TextToSpeech
25 | import kotlinx.coroutines.suspendCancellableCoroutine
26 | import java.util.*
27 | import kotlin.coroutines.resume
28 |
29 | class TTS(
30 | private val context: Context,
31 | private val locale: Locale = Locale.US,
32 | ) {
33 | private lateinit var tts: TextToSpeech
34 | private var ttsLang: Int = 0
35 |
36 | suspend fun getTts(): TextToSpeech? {
37 | return suspendCancellableCoroutine { continuation ->
38 | tts = TextToSpeech(context) {
39 | if (it == TextToSpeech.SUCCESS) {
40 | ttsLang = tts.setLanguage(locale)
41 | if (ttsLang == TextToSpeech.LANG_NOT_SUPPORTED) {
42 | continuation.resume(null)
43 | } else continuation.resume(tts)
44 | } else continuation.resume(null)
45 | }
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/Utility.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * Utility.kt Created by Yamin Siahmargooei at 2022/8/22
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | package io.github.yamin8000.owl.util
22 |
23 | import android.app.Activity
24 | import android.content.Context
25 | import android.content.ContextWrapper
26 | import android.os.Build
27 | import android.speech.tts.TextToSpeech
28 | import android.util.Log
29 | import androidx.compose.runtime.Immutable
30 | import androidx.compose.runtime.Stable
31 | import androidx.compose.runtime.saveable.Saver
32 | import io.github.yamin8000.owl.BuildConfig
33 | import io.github.yamin8000.owl.model.Definition
34 | import java.util.*
35 |
36 | fun Context.findActivity(): Activity? = when (this) {
37 | is Activity -> this
38 | is ContextWrapper -> baseContext.findActivity()
39 | else -> null
40 | }
41 |
42 | @Suppress("DEPRECATION")
43 | fun getCurrentLocale(
44 | context: Context
45 | ): Locale {
46 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
47 | context.resources.configuration.locales.get(0)
48 | } else context.resources.configuration.locale
49 | }
50 |
51 | fun TextToSpeech.speak(
52 | text: String
53 | ) {
54 | speak(text, TextToSpeech.QUEUE_FLUSH, null, null)
55 | }
56 |
57 | @Suppress("unused")
58 | @Stable
59 | class StableHolder(val item: T) {
60 | operator fun component1(): T = item
61 | }
62 |
63 | @Immutable
64 | class ImmutableHolder(val item: T) {
65 | operator fun component1(): T = item
66 | }
67 |
68 | val DefinitionListSaver = getImmutableHolderSaver>()
69 |
70 | fun getImmutableHolderSaver(): Saver, T> = Saver(
71 | save = { it.item },
72 | restore = { ImmutableHolder(it) }
73 | )
74 |
75 | fun log(
76 | message: String
77 | ) {
78 | if (BuildConfig.DEBUG)
79 | Log.d(Constants.LOG_TAG, message)
80 | }
81 |
82 | fun log(
83 | exception: Exception
84 | ) {
85 | log(exception.stackTraceToString())
86 | }
--------------------------------------------------------------------------------
/app/src/main/java/io/github/yamin8000/owl/util/list/ListSatiation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl/Owl.app.main
3 | * ListSatiation.kt Copyrighted by Yamin Siahmargooei at 2023/1/7
4 | * ListSatiation.kt Last modified at 2023/1/7
5 | * This file is part of Owl/Owl.app.main.
6 | * Copyright (C) 2023 Yamin Siahmargooei
7 | *
8 | * Owl/Owl.app.main is free software: you can redistribute it and/or modify
9 | * it under the terms of the GNU General Public License as published by
10 | * the Free Software Foundation, either version 3 of the License, or
11 | * (at your option) any later version.
12 | *
13 | * Owl/Owl.app.main is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with Owl. If not, see .
20 | */
21 |
22 | package io.github.yamin8000.owl.util.list
23 |
24 | enum class ListSatiation {
25 | Empty, Partial
26 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
20 |
21 |
26 |
29 |
34 |
39 |
44 |
49 |
54 |
59 |
64 |
69 |
74 |
79 |
84 |
89 |
94 |
99 |
104 |
109 |
114 |
119 |
124 |
129 |
134 |
139 |
144 |
149 |
154 |
159 |
164 |
169 |
174 |
179 |
184 |
189 |
190 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
20 |
25 |
30 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/font/samimbold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/font/samimbold.ttf
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-fa/strings.xml:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 | جغدک
23 | جستجو
24 | واژهای برای جستجو بنویسید
25 | واژههای برگزیده
26 | جستجوهای پیشین
27 | واژه تصادفی
28 | خطا در برقراری ارتباط با اینترنت، خطا ممکن است به خاطر محدودیت های اینترنت باشد
29 | سرور برنامه تحت فشار است، لطفا چند دقیقه دیگر تلاش کنید
30 | توضیحی برای این کلمه یافت نشد
31 | خطای احراز هویت با سرور برنامه
32 | متن کپی شد
33 | این یک برنامه آزاد طبق پروانه گنو است که توضیحات بیشتر آن در ادامه آورده شده است
34 | لوگو پروانه برنامه GPLv3
35 | فرهنگ واژگان انگلیسی به انگلیسی جغد، برگرفته از فرهنگ واژگان
36 | به برگزیدهها اضافه شد
37 | پاک کردن
38 | خطای پیش بینی نشده
39 | عبارتی وارد نشده
40 | اشتراک گذاری
41 | این متن توسط برنامه جغدک تولید شده
42 | پاک کردن همه
43 | تنظیمات
44 | زمینه
45 | در نسخه های اندروید 12 به بعد زمینه برنامه بر اساس رنگ قالب تصویر پس زمینه گوشی شما تعیین می شود
46 | هماهنگ سیستم
47 | روشن
48 | تاریک
49 | زبان متن به گفتار
50 | درباره
51 | نگارش
52 | تلفظ
53 | واژه
54 | اموجی
55 | نمونه
56 | معنی
57 | نوع
58 | عمومی
59 | لرزش در زمان پیمایش لیست
60 | لغو
61 | این واژه پیش از این به برگزیدهها اضافه شده است.
62 | پاک کردن
63 | صدای بلندگو را زیاد کنید.
64 |
--------------------------------------------------------------------------------
/app/src/main/res/values-hu/strings.xml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 | Owl
24 | Keresés
25 | Írj be egy szót a kereséshez
26 | Kedvenc Szavak
27 | Keresési Előzmények
28 | Véletlenszerű Szó
29 | Nincs kapcsolat a szerverrel. Az adatok előfordulhat, hogy a gyorsítótárból kerülnek betöltésre.
30 | A szerver elfoglalt, próbáld újra!
31 | Nem található definíció a szóra.
32 | Hitelesítési Hiba
33 | Szöveg másolva.
34 | Ez egy ingyenes applikáció a GNU licensz alatt, tudj meg többet:
35 | GPLv3 Licensz Logó
36 | Angol-Angol szótár alapján:
37 | Hozzáadva a kedvencekhez
38 | Kiürítés
39 | Váratlan hiba!
40 | Semmi sem került bevitelre.
41 | Megosztás
42 | Ezt a szöveget az Owl app generálta
43 | Mind kiürítése
44 | Beállítások
45 | Téma
46 | Android 12-n és afelett az alkalmazásod témája a háttérképed színei alapján készül el
47 | Rendszer
48 | Világos
49 | Sötét
50 | Szövegből-Beszéd Nyelve
51 | Az alkalmazásról
52 | Verzió
53 | Kiejtés
54 | Szó
55 | Emoji
56 | Példa
57 | Definíció
58 | Típus
59 | Általános
60 | Rezgés görgetéskor
61 | Mégse
62 | Ez a szó már a kedvencek között van.
63 | Törlés
64 | Növeld meg a hangerődet
65 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
21 |
22 |
23 | #BB0055
24 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 | Owl
23 | Search
24 | Enter a word to search
25 | Favourite Words
26 | Search History
27 | Random Word
28 | No connection to the server. Data maybe loaded from the cache.
29 | Server is busy, try again!
30 | No definition for the word found.
31 | Authentication Error
32 | Text copied.
33 | This is a free application under GNU license, see more:
34 | GPLv3 License Logo
35 | English to English Dictionary, based on:
36 | https://github.com/yamin8000/Owl2
37 | https://raw.githubusercontent.com/yamin8000/Owl2/master/LICENSE
38 | https://owlbot.info
39 | Added to favourites
40 | Clear
41 | Unexpected error!
42 | Nothing is entered.
43 | Share
44 | This text is generated using Owl app
45 | Clear All
46 | Settings
47 | Theme
48 | On Android 12+ your app theme colors are based on your home screen background
49 | System
50 | Light
51 | Dark
52 | Text-to-Speech Language
53 | About
54 | Version
55 | Pronunciation
56 | Word
57 | Emoji
58 | Example
59 | Definition
60 | Type
61 | This text is extracted from Owlbot Dictionary.
62 | General
63 | Vibrate on scroll
64 | Cancel
65 | This word is already added to the favorites.
66 | Delete
67 | Increase your volume
68 |
--------------------------------------------------------------------------------
/app/src/main/res/values/themes.xml:
--------------------------------------------------------------------------------
1 |
20 |
21 |
22 |
23 |
25 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext {
3 | compose_libs_version = '1.4.3'
4 | compose_ui_libs_version = '1.4.3'
5 | compose_compiler_version = '1.4.8'
6 | }
7 | }/*
8 | * Owl: an android app for Owlbot Dictionary API
9 | * build.gradle Created by Yamin Siahmargooei at 2022/6/16
10 | * This file is part of Owl.
11 | * Copyright (C) 2022 Yamin Siahmargooei
12 | *
13 | * Owl is free software: you can redistribute it and/or modify
14 | * it under the terms of the GNU General Public License as published by
15 | * the Free Software Foundation, either version 3 of the License, or
16 | * (at your option) any later version.
17 | *
18 | * Owl is distributed in the hope that it will be useful,
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 | * GNU General Public License for more details.
22 | *
23 | * You should have received a copy of the GNU General Public License
24 | * along with Owl. If not, see .
25 | */
26 |
27 | plugins {
28 | id 'com.android.application' version '8.0.2' apply false
29 | id 'com.android.library' version '8.0.2' apply false
30 | id 'org.jetbrains.kotlin.android' version '1.8.22' apply false
31 | id 'com.google.devtools.ksp' version '1.8.22-1.0.11'
32 | }
33 |
34 | task clean(type: Delete) {
35 | delete rootProject.buildDir
36 | }
37 |
38 | subprojects {
39 | tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
40 | kotlinOptions {
41 | freeCompilerArgs += [
42 | "-P",
43 | "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" +
44 | project.buildDir.absolutePath + "/compose_metrics"
45 | ]
46 | freeCompilerArgs += [
47 | "-P",
48 | "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" +
49 | project.buildDir.absolutePath + "/compose_metrics"
50 | ]
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Owl: an android app for Owlbot Dictionary API
3 | # gradle.properties Created by Yamin Siahmargooei at 2022/6/16
4 | # This file is part of Owl.
5 | # Copyright (C) 2022 Yamin Siahmargooei
6 | #
7 | # Owl is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # Owl is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU General Public License
18 | # along with Owl. If not, see .
19 | #
20 | # Project-wide Gradle settings.
21 | # IDE (e.g. Android Studio) users:
22 | # Gradle settings configured through the IDE *will override*
23 | # any settings specified in this file.
24 | # For more details on how to configure your build environment visit
25 | # http://www.gradle.org/docs/current/userguide/build_environment.html
26 | # Specifies the JVM arguments used for the daemon process.
27 | # The setting is particularly useful for tweaking memory settings.
28 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
29 | # When configured, Gradle will run in incubating parallel mode.
30 | # This option should only be used with decoupled projects. More details, visit
31 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
32 | # org.gradle.parallel=true
33 | # AndroidX package structure to make it clearer which packages are bundled with the
34 | # Android operating system, and which are packaged with your app"s APK
35 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
36 | android.useAndroidX=true
37 | # Kotlin code style for this project: "official" or "obsolete":
38 | kotlin.code.style=official
39 | # Enables namespacing of each library's R class so that its R class includes only the
40 | # resources declared in the library itself and none from the library's dependencies,
41 | # thereby reducing the size of the R class for that library
42 | android.enableR8.fullMode=false
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jul 07 12:25:23 GMT+03:30 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
5 | networkTimeout=10000
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | #
21 | # Gradle start up script for POSIX generated by Gradle.
22 | #
23 | # Important for running:
24 | #
25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
26 | # noncompliant, but you have some other compliant shell such as ksh or
27 | # bash, then to run this script, type that shell name before the whole
28 | # command line, like:
29 | #
30 | # ksh Gradle
31 | #
32 | # Busybox and similar reduced shells will NOT work, because this script
33 | # requires all of these POSIX shell features:
34 | # * functions;
35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
37 | # * compound commands having a testable exit status, especially «case»;
38 | # * various built-in commands including «command», «set», and «ulimit».
39 | #
40 | # Important for patching:
41 | #
42 | # (2) This script targets any POSIX shell, so it avoids extensions provided
43 | # by Bash, Ksh, etc; in particular arrays are avoided.
44 | #
45 | # The "traditional" practice of packing multiple parameters into a
46 | # space-separated string is a well documented source of bugs and security
47 | # problems, so this is (mostly) avoided, by progressively accumulating
48 | # options in "$@", and eventually passing that to Java.
49 | #
50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
52 | # see the in-line comments for details.
53 | #
54 | # There are tweaks for specific operating systems such as AIX, CygWin,
55 | # Darwin, MinGW, and NonStop.
56 | #
57 | # (3) This script is generated from the Groovy template
58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
59 | # within the Gradle project.
60 | #
61 | # You can find Gradle at https://github.com/gradle/gradle/.
62 | #
63 | ##############################################################################
64 |
65 | # Attempt to set APP_HOME
66 |
67 | # Resolve links: $0 may be a link
68 | app_path=$0
69 |
70 | # Need this for daisy-chained symlinks.
71 | while
72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
73 | [ -h "$app_path" ]
74 | do
75 | ls=$( ls -ld "$app_path" )
76 | link=${ls#*' -> '}
77 | case $link in #(
78 | /*) app_path=$link ;; #(
79 | *) app_path=$APP_HOME$link ;;
80 | esac
81 | done
82 |
83 | # This is normally unused
84 | # shellcheck disable=SC2034
85 | APP_BASE_NAME=${0##*/}
86 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
87 |
88 | # Use the maximum available, or set MAX_FD != -1 to use that value.
89 | MAX_FD=maximum
90 |
91 | warn () {
92 | echo "$*"
93 | } >&2
94 |
95 | die () {
96 | echo
97 | echo "$*"
98 | echo
99 | exit 1
100 | } >&2
101 |
102 | # OS specific support (must be 'true' or 'false').
103 | cygwin=false
104 | msys=false
105 | darwin=false
106 | nonstop=false
107 | case "$( uname )" in #(
108 | CYGWIN* ) cygwin=true ;; #(
109 | Darwin* ) darwin=true ;; #(
110 | MSYS* | MINGW* ) msys=true ;; #(
111 | NONSTOP* ) nonstop=true ;;
112 | esac
113 |
114 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
115 |
116 |
117 | # Determine the Java command to use to start the JVM.
118 | if [ -n "$JAVA_HOME" ] ; then
119 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
120 | # IBM's JDK on AIX uses strange locations for the executables
121 | JAVACMD=$JAVA_HOME/jre/sh/java
122 | else
123 | JAVACMD=$JAVA_HOME/bin/java
124 | fi
125 | if [ ! -x "$JAVACMD" ] ; then
126 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
127 |
128 | Please set the JAVA_HOME variable in your environment to match the
129 | location of your Java installation."
130 | fi
131 | else
132 | JAVACMD=java
133 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
134 |
135 | Please set the JAVA_HOME variable in your environment to match the
136 | location of your Java installation."
137 | fi
138 |
139 | # Increase the maximum file descriptors if we can.
140 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
141 | case $MAX_FD in #(
142 | max*)
143 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
144 | # shellcheck disable=SC3045
145 | MAX_FD=$( ulimit -H -n ) ||
146 | warn "Could not query maximum file descriptor limit"
147 | esac
148 | case $MAX_FD in #(
149 | '' | soft) :;; #(
150 | *)
151 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
152 | # shellcheck disable=SC3045
153 | ulimit -n "$MAX_FD" ||
154 | warn "Could not set maximum file descriptor limit to $MAX_FD"
155 | esac
156 | fi
157 |
158 | # Collect all arguments for the java command, stacking in reverse order:
159 | # * args from the command line
160 | # * the main class name
161 | # * -classpath
162 | # * -D...appname settings
163 | # * --module-path (only if needed)
164 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
165 |
166 | # For Cygwin or MSYS, switch paths to Windows format before running java
167 | if "$cygwin" || "$msys" ; then
168 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
169 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
170 |
171 | JAVACMD=$( cygpath --unix "$JAVACMD" )
172 |
173 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
174 | for arg do
175 | if
176 | case $arg in #(
177 | -*) false ;; # don't mess with options #(
178 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
179 | [ -e "$t" ] ;; #(
180 | *) false ;;
181 | esac
182 | then
183 | arg=$( cygpath --path --ignore --mixed "$arg" )
184 | fi
185 | # Roll the args list around exactly as many times as the number of
186 | # args, so each arg winds up back in the position where it started, but
187 | # possibly modified.
188 | #
189 | # NB: a `for` loop captures its iteration list before it begins, so
190 | # changing the positional parameters here affects neither the number of
191 | # iterations, nor the values presented in `arg`.
192 | shift # remove old arg
193 | set -- "$@" "$arg" # push replacement arg
194 | done
195 | fi
196 |
197 |
198 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
199 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
200 |
201 | # Collect all arguments for the java command;
202 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
203 | # shell script including quotes and variable substitutions, so put them in
204 | # double quotes to make sure that they get re-expanded; and
205 | # * put everything else in single quotes, so that it's not re-expanded.
206 |
207 | set -- \
208 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
209 | -classpath "$CLASSPATH" \
210 | org.gradle.wrapper.GradleWrapperMain \
211 | "$@"
212 |
213 | # Stop when "xargs" is not available.
214 | if ! command -v xargs >/dev/null 2>&1
215 | then
216 | die "xargs is not available"
217 | fi
218 |
219 | # Use "xargs" to parse quoted args.
220 | #
221 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
222 | #
223 | # In Bash we could simply go:
224 | #
225 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
226 | # set -- "${ARGS[@]}" "$@"
227 | #
228 | # but POSIX shell has neither arrays nor command substitution, so instead we
229 | # post-process each arg (as a line of input to sed) to backslash-escape any
230 | # character that might be a shell metacharacter, then use eval to reverse
231 | # that process (while maintaining the separation between arguments), and wrap
232 | # the whole thing up as a single "set" statement.
233 | #
234 | # This will of course break if any of these variables contains a newline or
235 | # an unmatched quote.
236 | #
237 |
238 | eval "set -- $(
239 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
240 | xargs -n1 |
241 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
242 | tr '\n' ' '
243 | )" '"$@"'
244 |
245 | exec "$JAVACMD" "$@"
246 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | @rem This is normally unused
30 | set APP_BASE_NAME=%~n0
31 | set APP_HOME=%DIRNAME%
32 |
33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
35 |
36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
38 |
39 | @rem Find java.exe
40 | if defined JAVA_HOME goto findJavaFromJavaHome
41 |
42 | set JAVA_EXE=java.exe
43 | %JAVA_EXE% -version >NUL 2>&1
44 | if %ERRORLEVEL% equ 0 goto execute
45 |
46 | echo.
47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
48 | echo.
49 | echo Please set the JAVA_HOME variable in your environment to match the
50 | echo location of your Java installation.
51 |
52 | goto fail
53 |
54 | :findJavaFromJavaHome
55 | set JAVA_HOME=%JAVA_HOME:"=%
56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
57 |
58 | if exist "%JAVA_EXE%" goto execute
59 |
60 | echo.
61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
62 | echo.
63 | echo Please set the JAVA_HOME variable in your environment to match the
64 | echo location of your Java installation.
65 |
66 | goto fail
67 |
68 | :execute
69 | @rem Setup the command line
70 |
71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
72 |
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 %*
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if %ERRORLEVEL% equ 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 | set EXIT_CODE=%ERRORLEVEL%
85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87 | exit /b %EXIT_CODE%
88 |
89 | :mainEnd
90 | if "%OS%"=="Windows_NT" endlocal
91 |
92 | :omega
93 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/screenshots/1.0.1/Screenshot_2022-08-24-02-51-48-048_io.github.yamin8000.owl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.1/Screenshot_2022-08-24-02-51-48-048_io.github.yamin8000.owl.jpg
--------------------------------------------------------------------------------
/screenshots/1.0.4/photo_2022-09-26_09-12-54.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.4/photo_2022-09-26_09-12-54.png
--------------------------------------------------------------------------------
/screenshots/1.0.4/photo_2022-09-26_09-12-55 (2).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.4/photo_2022-09-26_09-12-55 (2).png
--------------------------------------------------------------------------------
/screenshots/1.0.7/photo_2022-11-10_22-27-32.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.7/photo_2022-11-10_22-27-32.jpg
--------------------------------------------------------------------------------
/screenshots/1.0.7/photo_2022-11-10_22-27-33.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.7/photo_2022-11-10_22-27-33.jpg
--------------------------------------------------------------------------------
/screenshots/1.0.7/photo_2022-11-10_22-27-34.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.7/photo_2022-11-10_22-27-34.jpg
--------------------------------------------------------------------------------
/screenshots/1.0.7/photo_2022-11-10_22-27-36.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.7/photo_2022-11-10_22-27-36.jpg
--------------------------------------------------------------------------------
/screenshots/1.0.7/photo_2022-11-10_22-27-37.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.7/photo_2022-11-10_22-27-37.jpg
--------------------------------------------------------------------------------
/screenshots/1.0.7/photo_2022-11-10_22-27-38.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yamin8000/Owl2/abf80da26053409758c41c5d2b4e88116d42fba4/screenshots/1.0.7/photo_2022-11-10_22-27-38.jpg
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * Owl: an android app for Owlbot Dictionary API
3 | * settings.gradle Created by Yamin Siahmargooei at 2022/6/16
4 | * This file is part of Owl.
5 | * Copyright (C) 2022 Yamin Siahmargooei
6 | *
7 | * Owl is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 | *
12 | * Owl is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU General Public License for more details.
16 | *
17 | * You should have received a copy of the GNU General Public License
18 | * along with Owl. If not, see .
19 | */
20 |
21 | pluginManagement {
22 | repositories {
23 | gradlePluginPortal()
24 | google()
25 | mavenCentral()
26 | }
27 | }
28 | dependencyResolutionManagement {
29 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
30 | repositories {
31 | google()
32 | mavenCentral()
33 | }
34 | }
35 | rootProject.name = "Owl2"
36 | include ':app'
37 |
--------------------------------------------------------------------------------