mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-10 11:08:52 -06:00
Compare commits
5 Commits
6a9c3a36eb
...
fix/stackw
| Author | SHA1 | Date | |
|---|---|---|---|
|
2154d8c192
|
|||
|
4c5a722dc5
|
|||
| ee39ff0eda | |||
| 13af054214 | |||
| fcbb586e80 |
@@ -1,11 +1,11 @@
|
|||||||
plugins {
|
plugins {
|
||||||
val kotlinVersion = "1.7.10"
|
val kotlinVersion = "1.6.10"
|
||||||
id("com.android.application") version ("7.3.0-rc01") apply (false)
|
id("com.android.application") version ("7.0.3") apply (false)
|
||||||
id("org.jetbrains.kotlin.android") version kotlinVersion apply (false)
|
id("org.jetbrains.kotlin.android") version kotlinVersion apply (false)
|
||||||
id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false)
|
id("org.jetbrains.kotlin.kapt") version kotlinVersion apply (false)
|
||||||
id("org.jetbrains.kotlin.android.extensions") version kotlinVersion apply (false)
|
id("org.jetbrains.kotlin.android.extensions") version kotlinVersion apply (false)
|
||||||
id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false)
|
id("org.jetbrains.kotlin.multiplatform") version kotlinVersion apply (false)
|
||||||
id("org.jlleitschuh.gradle.ktlint") version "11.0.0"
|
id("org.jlleitschuh.gradle.ktlint") version "10.2.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply {
|
apply {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ The repository will be downloaded to the directory `uhabits`.
|
|||||||
2. When the IDE asks you for the project location, select `uhabits` and click "Ok".
|
2. When the IDE asks you for the project location, select `uhabits` and click "Ok".
|
||||||
3. Android Studio will spend some time indexing the project. When this is complete, click the toolbar icon "Sync Project with Gradle File", located near the right corner of the top toolbar.
|
3. Android Studio will spend some time indexing the project. When this is complete, click the toolbar icon "Sync Project with Gradle File", located near the right corner of the top toolbar.
|
||||||
4. The operation will likely fail several times due to missing Android SDK components. Each time it fails, click the link "Install missing platforms", "Install build tools", etc, and try again.
|
4. The operation will likely fail several times due to missing Android SDK components. Each time it fails, click the link "Install missing platforms", "Install build tools", etc, and try again.
|
||||||
5. To test the application, create a virtual Android device using the menu "Tools" and "AVD Manager". The default options should work fine, but feel free to customize the device.
|
5. To test the application, create a virtual Android device using the menu "Tools" and "AVD Manager". The default options should work fine, but free to customize the device.
|
||||||
6. Click the menu "Run" and "uhabits-android". The application should launch.
|
6. Click the menu "Run" and "uhabits-android". The application should launch.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ tasks.compileLint {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
|
|
||||||
compileSdk = 32
|
compileSdk = 31
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
versionCode = 20100
|
versionCode = 20100
|
||||||
@@ -68,6 +68,12 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lint {
|
||||||
|
isCheckReleaseBuilds = false
|
||||||
|
isAbortOnError = false
|
||||||
|
disable("GoogleAppIndexingWarning")
|
||||||
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
isCoreLibraryDesugaringEnabled = true
|
isCoreLibraryDesugaringEnabled = true
|
||||||
targetCompatibility(JavaVersion.VERSION_1_8)
|
targetCompatibility(JavaVersion.VERSION_1_8)
|
||||||
@@ -80,25 +86,25 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
val daggerVersion = "2.43.2"
|
val daggerVersion = "2.41"
|
||||||
val kotlinVersion = "1.7.10"
|
val kotlinVersion = "1.6.21"
|
||||||
val kxCoroutinesVersion = "1.6.4"
|
val kxCoroutinesVersion = "1.6.1"
|
||||||
val ktorVersion = "1.6.8"
|
val ktorVersion = "1.6.8"
|
||||||
val espressoVersion = "3.4.0"
|
val espressoVersion = "3.4.0"
|
||||||
|
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion")
|
androidTestImplementation("androidx.test.espresso:espresso-contrib:$espressoVersion")
|
||||||
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
|
androidTestImplementation("androidx.test.espresso:espresso-core:$espressoVersion")
|
||||||
androidTestImplementation("com.google.dagger:dagger:$daggerVersion")
|
androidTestImplementation("com.google.dagger:dagger:$daggerVersion")
|
||||||
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.3")
|
androidTestImplementation("com.linkedin.dexmaker:dexmaker-mockito:2.28.1")
|
||||||
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
|
androidTestImplementation("io.ktor:ktor-client-mock:$ktorVersion")
|
||||||
androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion")
|
androidTestImplementation("io.ktor:ktor-jackson:$ktorVersion")
|
||||||
androidTestImplementation("androidx.annotation:annotation:1.4.0")
|
androidTestImplementation("androidx.annotation:annotation:1.3.0")
|
||||||
androidTestImplementation("androidx.test.ext:junit:1.1.3")
|
androidTestImplementation("androidx.test.ext:junit:1.1.3")
|
||||||
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
|
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0")
|
||||||
androidTestImplementation("androidx.test:rules:1.4.0")
|
androidTestImplementation("androidx.test:rules:1.4.0")
|
||||||
androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
androidTestImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
||||||
compileOnly("javax.annotation:jsr250-api:1.0")
|
compileOnly("javax.annotation:jsr250-api:1.0")
|
||||||
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.2")
|
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5")
|
||||||
implementation("com.github.AppIntro:AppIntro:6.2.0")
|
implementation("com.github.AppIntro:AppIntro:6.2.0")
|
||||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
||||||
implementation("com.google.dagger:dagger:$daggerVersion")
|
implementation("com.google.dagger:dagger:$daggerVersion")
|
||||||
@@ -110,10 +116,10 @@ dependencies {
|
|||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kxCoroutinesVersion")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kxCoroutinesVersion")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kxCoroutinesVersion")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kxCoroutinesVersion")
|
||||||
implementation("androidx.appcompat:appcompat:1.5.0")
|
implementation("androidx.appcompat:appcompat:1.4.1")
|
||||||
implementation("androidx.legacy:legacy-preference-v14:1.0.0")
|
implementation("androidx.legacy:legacy-preference-v14:1.0.0")
|
||||||
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
||||||
implementation("com.google.android.material:material:1.6.1")
|
implementation("com.google.android.material:material:1.5.0")
|
||||||
implementation("com.opencsv:opencsv:5.6")
|
implementation("com.opencsv:opencsv:5.6")
|
||||||
implementation(project(":uhabits-core"))
|
implementation(project(":uhabits-core"))
|
||||||
kapt("com.google.dagger:dagger-compiler:$daggerVersion")
|
kapt("com.google.dagger:dagger-compiler:$daggerVersion")
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ object ListHabitsSteps {
|
|||||||
clickViewWithId(R.id.action_filter)
|
clickViewWithId(R.id.action_filter)
|
||||||
CommonSteps.clickText(R.string.hide_completed)
|
CommonSteps.clickText(R.string.hide_completed)
|
||||||
}
|
}
|
||||||
else -> throw RuntimeException()
|
|
||||||
}
|
}
|
||||||
device.waitForIdle()
|
device.waitForIdle()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import org.isoron.uhabits.utils.toPaletteColor
|
|||||||
class ColorPickerDialog : ColorPickerDialog() {
|
class ColorPickerDialog : ColorPickerDialog() {
|
||||||
fun setListener(callback: OnColorPickedCallback) {
|
fun setListener(callback: OnColorPickedCallback) {
|
||||||
super.setOnColorSelectedListener { c: Int ->
|
super.setOnColorSelectedListener { c: Int ->
|
||||||
val pc = c.toPaletteColor(requireContext())
|
val pc = c.toPaletteColor(context!!)
|
||||||
callback.onColorPicked(pc)
|
callback.onColorPicked(pc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
|
|||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
clearCurrentDialog()
|
clearCurrentDialog()
|
||||||
val component = (requireActivity().application as HabitsApplication).component
|
val component = (activity!!.application as HabitsApplication).component
|
||||||
commandRunner = component.commandRunner
|
commandRunner = component.commandRunner
|
||||||
habit = component.habitList.getById(requireArguments().getLong("habit"))!!
|
habit = component.habitList.getById(arguments!!.getLong("habit"))!!
|
||||||
preferences = component.preferences
|
preferences = component.preferences
|
||||||
|
|
||||||
val themeSwitcher = AndroidThemeSwitcher(requireActivity(), preferences)
|
val themeSwitcher = AndroidThemeSwitcher(activity!!, preferences)
|
||||||
themeSwitcher.apply()
|
themeSwitcher.apply()
|
||||||
|
|
||||||
chart = HistoryChart(
|
chart = HistoryChart(
|
||||||
@@ -71,10 +71,10 @@ class HistoryEditorDialog : AppCompatDialogFragment(), CommandRunner.Listener {
|
|||||||
onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
|
onDateClickedListener = onDateClickedListener ?: object : OnDateClickedListener {},
|
||||||
padding = 10.0,
|
padding = 10.0,
|
||||||
)
|
)
|
||||||
dataView = AndroidDataView(requireContext(), null)
|
dataView = AndroidDataView(context!!, null)
|
||||||
dataView.view = chart!!
|
dataView.view = chart!!
|
||||||
|
|
||||||
val dialog = Dialog(requireContext()).apply {
|
val dialog = Dialog(context!!).apply {
|
||||||
val metrics = resources.displayMetrics
|
val metrics = resources.displayMetrics
|
||||||
val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height)
|
val maxHeight = resources.getDimensionPixelSize(R.dimen.history_editor_max_height)
|
||||||
setContentView(dataView)
|
setContentView(dataView)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class WeekdayPickerDialog :
|
|||||||
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
val builder = AlertDialog.Builder(
|
val builder = AlertDialog.Builder(
|
||||||
requireActivity()
|
activity!!
|
||||||
)
|
)
|
||||||
builder
|
builder
|
||||||
.setTitle(R.string.select_weekdays)
|
.setTitle(R.string.select_weekdays)
|
||||||
|
|||||||
@@ -63,9 +63,7 @@ class FrequencyChart : ScrollableChart {
|
|||||||
private var primaryColor = 0
|
private var primaryColor = 0
|
||||||
private var isBackgroundTransparent = false
|
private var isBackgroundTransparent = false
|
||||||
private lateinit var frequency: HashMap<Timestamp, Array<Int>>
|
private lateinit var frequency: HashMap<Timestamp, Array<Int>>
|
||||||
private var maxFreq = 0
|
|
||||||
private var firstWeekday = Calendar.SUNDAY
|
private var firstWeekday = Calendar.SUNDAY
|
||||||
private var isNumerical: Boolean = false
|
|
||||||
|
|
||||||
constructor(context: Context?) : super(context) {
|
constructor(context: Context?) : super(context) {
|
||||||
init()
|
init()
|
||||||
@@ -82,14 +80,8 @@ class FrequencyChart : ScrollableChart {
|
|||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setIsNumerical(type: Boolean) {
|
|
||||||
isNumerical = type
|
|
||||||
postInvalidate()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setFrequency(frequency: java.util.HashMap<Timestamp, Array<Int>>) {
|
fun setFrequency(frequency: java.util.HashMap<Timestamp, Array<Int>>) {
|
||||||
this.frequency = frequency
|
this.frequency = frequency
|
||||||
maxFreq = getMaxFreq(frequency)
|
|
||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,15 +90,6 @@ class FrequencyChart : ScrollableChart {
|
|||||||
postInvalidate()
|
postInvalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getMaxFreq(frequency: HashMap<Timestamp, Array<Int>>): Int {
|
|
||||||
var maxValue = 1
|
|
||||||
for (values in frequency.values) for (value in values) maxValue = max(
|
|
||||||
value,
|
|
||||||
maxValue
|
|
||||||
)
|
|
||||||
return maxValue
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIsBackgroundTransparent(isBackgroundTransparent: Boolean) {
|
fun setIsBackgroundTransparent(isBackgroundTransparent: Boolean) {
|
||||||
this.isBackgroundTransparent = isBackgroundTransparent
|
this.isBackgroundTransparent = isBackgroundTransparent
|
||||||
initColors()
|
initColors()
|
||||||
@@ -230,7 +213,7 @@ class FrequencyChart : ScrollableChart {
|
|||||||
canvas.drawLine(rGrid.left, rGrid.top, rGrid.right, rGrid.top, pGrid!!)
|
canvas.drawLine(rGrid.left, rGrid.top, rGrid.right, rGrid.top, pGrid!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?, weekdayFrequency: Int) {
|
private fun drawMarker(canvas: Canvas, rect: RectF?, value: Int?, frequency: Int) {
|
||||||
// value can be negative when the entry is skipped
|
// value can be negative when the entry is skipped
|
||||||
val valueCopy = value?.let { max(0, it) }
|
val valueCopy = value?.let { max(0, it) }
|
||||||
|
|
||||||
@@ -238,8 +221,8 @@ class FrequencyChart : ScrollableChart {
|
|||||||
// maximal allowed mark radius
|
// maximal allowed mark radius
|
||||||
val maxRadius = (rect.height() - 2 * padding) / 2.0f
|
val maxRadius = (rect.height() - 2 * padding) / 2.0f
|
||||||
// the real mark radius is scaled down by a factor depending on the maximal frequency
|
// the real mark radius is scaled down by a factor depending on the maximal frequency
|
||||||
val scalingFactor = if (isNumerical) maxFreq else weekdayFrequency
|
|
||||||
val scale = 1.0f / scalingFactor * valueCopy!!
|
val scale = 1.0f / frequency * valueCopy!!
|
||||||
val radius = maxRadius * scale
|
val radius = maxRadius * scale
|
||||||
val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt())
|
val colorIndex = min((colors.size - 1), ((colors.size - 1) * scale).roundToInt())
|
||||||
pGraph!!.color = colors[colorIndex]
|
pGraph!!.color = colors[colorIndex]
|
||||||
@@ -302,6 +285,5 @@ class FrequencyChart : ScrollableChart {
|
|||||||
frequency[Timestamp(date)] = values
|
frequency[Timestamp(date)] = values
|
||||||
date.add(Calendar.MONTH, -1)
|
date.add(Calendar.MONTH, -1)
|
||||||
}
|
}
|
||||||
maxFreq = getMaxFreq(frequency)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,13 +40,13 @@ class HabitTypeDialog : AppCompatDialogFragment() {
|
|||||||
val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
|
val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
binding.buttonYesNo.setOnClickListener {
|
binding.buttonYesNo.setOnClickListener {
|
||||||
val intent = IntentFactory().startEditActivity(requireActivity(), HabitType.YES_NO.value)
|
val intent = IntentFactory().startEditActivity(activity!!, HabitType.YES_NO.value)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.buttonMeasurable.setOnClickListener {
|
binding.buttonMeasurable.setOnClickListener {
|
||||||
val intent = IntentFactory().startEditActivity(requireActivity(), HabitType.NUMERICAL.value)
|
val intent = IntentFactory().startEditActivity(activity!!, HabitType.NUMERICAL.value)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
|
|||||||
Thread.setDefaultUncaughtExceptionHandler(BaseExceptionHandler(this))
|
Thread.setDefaultUncaughtExceptionHandler(BaseExceptionHandler(this))
|
||||||
component.listHabitsBehavior.onStartup()
|
component.listHabitsBehavior.onStartup()
|
||||||
setContentView(rootView)
|
setContentView(rootView)
|
||||||
parseIntents()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
@@ -110,6 +109,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
|
|||||||
if (prefs.theme == THEME_DARK && prefs.isPureBlackEnabled != pureBlack) {
|
if (prefs.theme == THEME_DARK && prefs.isPureBlackEnabled != pureBlack) {
|
||||||
restartWithFade(ListHabitsActivity::class.java)
|
restartWithFade(ListHabitsActivity::class.java)
|
||||||
}
|
}
|
||||||
|
parseIntents()
|
||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +129,7 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun parseIntents() {
|
private fun parseIntents() {
|
||||||
|
if (intent == null) return
|
||||||
if (intent.action == ACTION_EDIT) {
|
if (intent.action == ACTION_EDIT) {
|
||||||
val habitId = intent.extras?.getLong("habit")
|
val habitId = intent.extras?.getLong("habit")
|
||||||
val timestamp = intent.extras?.getLong("timestamp")
|
val timestamp = intent.extras?.getLong("timestamp")
|
||||||
@@ -137,6 +138,12 @@ class ListHabitsActivity : AppCompatActivity(), Preferences.Listener {
|
|||||||
component.listHabitsBehavior.onEdit(habit, Timestamp(timestamp))
|
component.listHabitsBehavior.onEdit(habit, Timestamp(timestamp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
intent = null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
setIntent(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -221,7 +221,6 @@ class ShowHabitActivity : AppCompatActivity(), CommandRunner.Listener {
|
|||||||
ShowHabitMenuPresenter.Message.COULD_NOT_EXPORT -> {
|
ShowHabitMenuPresenter.Message.COULD_NOT_EXPORT -> {
|
||||||
showMessage(resources.getString(R.string.could_not_export))
|
showMessage(resources.getString(R.string.could_not_export))
|
||||||
}
|
}
|
||||||
else -> {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(co
|
|||||||
fun setState(state: FrequencyCardState) {
|
fun setState(state: FrequencyCardState) {
|
||||||
val androidColor = state.theme.color(state.color).toInt()
|
val androidColor = state.theme.color(state.color).toInt()
|
||||||
binding.frequencyChart.setFrequency(state.frequency)
|
binding.frequencyChart.setFrequency(state.frequency)
|
||||||
binding.frequencyChart.setIsNumerical(state.isNumerical)
|
|
||||||
binding.frequencyChart.setFirstWeekday(state.firstWeekday)
|
binding.frequencyChart.setFirstWeekday(state.firstWeekday)
|
||||||
binding.title.setTextColor(androidColor)
|
binding.title.setTextColor(androidColor)
|
||||||
binding.frequencyChart.setColor(androidColor)
|
binding.frequencyChart.setColor(androidColor)
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
addPreferencesFromResource(R.xml.preferences)
|
addPreferencesFromResource(R.xml.preferences)
|
||||||
val appContext = requireContext().applicationContext
|
val appContext = context!!.applicationContext
|
||||||
if (appContext is HabitsApplication) {
|
if (appContext is HabitsApplication) {
|
||||||
prefs = appContext.component.preferences
|
prefs = appContext.component.preferences
|
||||||
widgetUpdater = appContext.component.widgetUpdater
|
widgetUpdater = appContext.component.widgetUpdater
|
||||||
@@ -99,9 +99,9 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
|
|||||||
return true
|
return true
|
||||||
} else if (key == "reminderCustomize") {
|
} else if (key == "reminderCustomize") {
|
||||||
if (SDK_INT < Build.VERSION_CODES.O) return true
|
if (SDK_INT < Build.VERSION_CODES.O) return true
|
||||||
createAndroidNotificationChannel(requireContext())
|
createAndroidNotificationChannel(context!!)
|
||||||
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
|
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
|
||||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
|
intent.putExtra(Settings.EXTRA_APP_PACKAGE, context!!.packageName)
|
||||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
|
intent.putExtra(Settings.EXTRA_CHANNEL_ID, NotificationTray.REMINDERS_CHANNEL_ID)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
return true
|
return true
|
||||||
@@ -111,7 +111,7 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
ringtoneManager = RingtoneManager(requireActivity())
|
ringtoneManager = RingtoneManager(activity!!)
|
||||||
sharedPrefs = preferenceManager.sharedPreferences
|
sharedPrefs = preferenceManager.sharedPreferences
|
||||||
sharedPrefs!!.registerOnSharedPreferenceChangeListener(this)
|
sharedPrefs!!.registerOnSharedPreferenceChangeListener(this)
|
||||||
if (!prefs.isDeveloper) {
|
if (!prefs.isDeveloper) {
|
||||||
@@ -154,8 +154,8 @@ class SettingsFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeLis
|
|||||||
val pref = findPreference(key)
|
val pref = findPreference(key)
|
||||||
pref.onPreferenceClickListener =
|
pref.onPreferenceClickListener =
|
||||||
Preference.OnPreferenceClickListener {
|
Preference.OnPreferenceClickListener {
|
||||||
requireActivity().setResult(result)
|
activity!!.setResult(result)
|
||||||
requireActivity().finish()
|
activity!!.finish()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,16 @@ package org.isoron.uhabits.intents
|
|||||||
|
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.app.PendingIntent.FLAG_IMMUTABLE
|
import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||||
|
import android.app.PendingIntent.FLAG_MUTABLE
|
||||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
import android.app.PendingIntent.getActivity
|
import android.app.PendingIntent.getActivity
|
||||||
import android.app.PendingIntent.getBroadcast
|
import android.app.PendingIntent.getBroadcast
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
import org.isoron.uhabits.activities.habits.list.ListHabitsActivity
|
import org.isoron.uhabits.activities.habits.list.ListHabitsActivity
|
||||||
|
import org.isoron.uhabits.activities.habits.show.ShowHabitActivity
|
||||||
import org.isoron.uhabits.core.AppScope
|
import org.isoron.uhabits.core.AppScope
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.Timestamp
|
import org.isoron.uhabits.core.models.Timestamp
|
||||||
@@ -89,6 +92,20 @@ class PendingIntentFactory
|
|||||||
)
|
)
|
||||||
.getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)!!
|
.getPendingIntent(0, FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT)!!
|
||||||
|
|
||||||
|
fun showHabitTemplate(): PendingIntent {
|
||||||
|
return getActivity(
|
||||||
|
context,
|
||||||
|
0,
|
||||||
|
Intent(context, ShowHabitActivity::class.java),
|
||||||
|
getIntentTemplateFlags()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showHabitFillIn(habit: Habit) =
|
||||||
|
Intent().apply {
|
||||||
|
data = Uri.parse(habit.uriString)
|
||||||
|
}
|
||||||
|
|
||||||
fun showReminder(
|
fun showReminder(
|
||||||
habit: Habit,
|
habit: Habit,
|
||||||
reminderTime: Long?,
|
reminderTime: Long?,
|
||||||
@@ -142,7 +159,7 @@ class PendingIntentFactory
|
|||||||
fun showNumberPicker(habit: Habit, timestamp: Timestamp): PendingIntent? {
|
fun showNumberPicker(habit: Habit, timestamp: Timestamp): PendingIntent? {
|
||||||
return getActivity(
|
return getActivity(
|
||||||
context,
|
context,
|
||||||
0,
|
(habit.id!! % Integer.MAX_VALUE).toInt() + 1,
|
||||||
Intent(context, ListHabitsActivity::class.java).apply {
|
Intent(context, ListHabitsActivity::class.java).apply {
|
||||||
action = ListHabitsActivity.ACTION_EDIT
|
action = ListHabitsActivity.ACTION_EDIT
|
||||||
putExtra("habit", habit.id)
|
putExtra("habit", habit.id)
|
||||||
@@ -151,4 +168,43 @@ class PendingIntentFactory
|
|||||||
FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
|
FLAG_IMMUTABLE or FLAG_UPDATE_CURRENT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showNumberPickerTemplate(): PendingIntent {
|
||||||
|
return getActivity(
|
||||||
|
context,
|
||||||
|
1,
|
||||||
|
Intent(context, ListHabitsActivity::class.java).apply {
|
||||||
|
action = ListHabitsActivity.ACTION_EDIT
|
||||||
|
},
|
||||||
|
getIntentTemplateFlags()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showNumberPickerFillIn(habit: Habit, timestamp: Timestamp) = Intent().apply {
|
||||||
|
putExtra("habit", habit.id)
|
||||||
|
putExtra("timestamp", timestamp.unixTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getIntentTemplateFlags(): Int {
|
||||||
|
var flags = 0
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
flags = flags or FLAG_MUTABLE
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toggleCheckmarkTemplate(): PendingIntent =
|
||||||
|
getBroadcast(
|
||||||
|
context,
|
||||||
|
2,
|
||||||
|
Intent(context, WidgetReceiver::class.java).apply {
|
||||||
|
action = WidgetReceiver.ACTION_TOGGLE_REPETITION
|
||||||
|
},
|
||||||
|
getIntentTemplateFlags()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun toggleCheckmarkFillIn(habit: Habit, timestamp: Timestamp) = Intent().apply {
|
||||||
|
data = Uri.parse(habit.uriString)
|
||||||
|
putExtra("timestamp", timestamp.unixTime)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ class FrequencyWidget(
|
|||||||
(widgetView.dataView as FrequencyChart).apply {
|
(widgetView.dataView as FrequencyChart).apply {
|
||||||
setFirstWeekday(firstWeekday)
|
setFirstWeekday(firstWeekday)
|
||||||
setColor(WidgetTheme().color(habit.color).toInt())
|
setColor(WidgetTheme().color(habit.color).toInt())
|
||||||
setIsNumerical(habit.isNumerical)
|
|
||||||
setFrequency(habit.originalEntries.computeWeekdayFrequency(habit.isNumerical))
|
setFrequency(habit.originalEntries.computeWeekdayFrequency(habit.isNumerical))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ class StackWidget(
|
|||||||
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
||||||
StackWidgetType.getStackWidgetEmptyViewId(widgetType)
|
StackWidgetType.getStackWidgetEmptyViewId(widgetType)
|
||||||
)
|
)
|
||||||
|
remoteViews.setPendingIntentTemplate(
|
||||||
|
StackWidgetType.getStackWidgetAdapterViewId(widgetType),
|
||||||
|
StackWidgetType.getPendingIntentTemplate(pendingIntentFactory, widgetType, habits)
|
||||||
|
)
|
||||||
return remoteViews
|
return remoteViews
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,11 +29,14 @@ import android.widget.RemoteViewsService
|
|||||||
import android.widget.RemoteViewsService.RemoteViewsFactory
|
import android.widget.RemoteViewsService.RemoteViewsFactory
|
||||||
import org.isoron.platform.utils.StringUtils.Companion.splitLongs
|
import org.isoron.platform.utils.StringUtils.Companion.splitLongs
|
||||||
import org.isoron.uhabits.HabitsApplication
|
import org.isoron.uhabits.HabitsApplication
|
||||||
|
import org.isoron.uhabits.R
|
||||||
import org.isoron.uhabits.core.models.Habit
|
import org.isoron.uhabits.core.models.Habit
|
||||||
import org.isoron.uhabits.core.models.HabitNotFoundException
|
import org.isoron.uhabits.core.models.HabitNotFoundException
|
||||||
import org.isoron.uhabits.core.preferences.Preferences
|
import org.isoron.uhabits.core.preferences.Preferences
|
||||||
|
import org.isoron.uhabits.core.utils.DateUtils.Companion.getToday
|
||||||
|
import org.isoron.uhabits.intents.IntentFactory
|
||||||
|
import org.isoron.uhabits.intents.PendingIntentFactory
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils.dpToPixels
|
import org.isoron.uhabits.utils.InterfaceUtils.dpToPixels
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
class StackWidgetService : RemoteViewsService() {
|
class StackWidgetService : RemoteViewsService() {
|
||||||
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
override fun onGetViewFactory(intent: Intent): RemoteViewsFactory {
|
||||||
@@ -54,7 +57,6 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
|
|||||||
)
|
)
|
||||||
private val habitIds: LongArray
|
private val habitIds: LongArray
|
||||||
private val widgetType: StackWidgetType
|
private val widgetType: StackWidgetType
|
||||||
private var remoteViews = ArrayList<RemoteViews>()
|
|
||||||
override fun onCreate() {}
|
override fun onCreate() {}
|
||||||
override fun onDestroy() {}
|
override fun onDestroy() {}
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
@@ -85,8 +87,26 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getViewAt(position: Int): RemoteViews? {
|
override fun getViewAt(position: Int): RemoteViews? {
|
||||||
Log.i("StackRemoteViewsFactory", "getViewAt $position")
|
Log.i("StackRemoteViewsFactory", "getViewAt $position started")
|
||||||
return if (0 <= position && position < remoteViews.size) remoteViews[position] else null
|
if (position < 0 || position >= habitIds.size) return null
|
||||||
|
val app = context.applicationContext as HabitsApplication
|
||||||
|
val prefs = app.component.preferences
|
||||||
|
val habitList = app.component.habitList
|
||||||
|
val options = AppWidgetManager.getInstance(context).getAppWidgetOptions(widgetId)
|
||||||
|
if (Looper.myLooper() == null) Looper.prepare()
|
||||||
|
val habits = habitIds.map { habitList.getById(it) ?: throw HabitNotFoundException() }
|
||||||
|
val h = habits[position]
|
||||||
|
val widget = constructWidget(h, prefs)
|
||||||
|
widget.setDimensions(getDimensionsFromOptions(context, options))
|
||||||
|
val landscapeViews = widget.landscapeRemoteViews
|
||||||
|
val portraitViews = widget.portraitRemoteViews
|
||||||
|
val factory = PendingIntentFactory(context, IntentFactory())
|
||||||
|
val intent = StackWidgetType.getIntentFillIn(factory, widgetType, h, habits, getToday())
|
||||||
|
landscapeViews.setOnClickFillInIntent(R.id.button, intent)
|
||||||
|
portraitViews.setOnClickFillInIntent(R.id.button, intent)
|
||||||
|
val remoteViews = RemoteViews(landscapeViews, portraitViews)
|
||||||
|
Log.i("StackRemoteViewsFactory", "getViewAt $position ended")
|
||||||
|
return remoteViews
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun constructWidget(
|
private fun constructWidget(
|
||||||
@@ -131,24 +151,6 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onDataSetChanged() {
|
override fun onDataSetChanged() {
|
||||||
Log.i("StackRemoteViewsFactory", "onDataSetChanged started")
|
|
||||||
val app = context.applicationContext as HabitsApplication
|
|
||||||
val prefs = app.component.preferences
|
|
||||||
val habitList = app.component.habitList
|
|
||||||
val options = AppWidgetManager.getInstance(context).getAppWidgetOptions(widgetId)
|
|
||||||
val newRemoteViews = ArrayList<RemoteViews>()
|
|
||||||
if (Looper.myLooper() == null) Looper.prepare()
|
|
||||||
for (id in habitIds) {
|
|
||||||
val h = habitList.getById(id) ?: throw HabitNotFoundException()
|
|
||||||
val widget = constructWidget(h, prefs)
|
|
||||||
widget.setDimensions(getDimensionsFromOptions(context, options))
|
|
||||||
val landscapeViews = widget.landscapeRemoteViews
|
|
||||||
val portraitViews = widget.portraitRemoteViews
|
|
||||||
newRemoteViews.add(RemoteViews(landscapeViews, portraitViews))
|
|
||||||
Log.i("StackRemoteViewsFactory", "onDataSetChanged constructed widget $id")
|
|
||||||
}
|
|
||||||
remoteViews = newRemoteViews
|
|
||||||
Log.i("StackRemoteViewsFactory", "onDataSetChanged ended")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -18,7 +18,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.widgets
|
package org.isoron.uhabits.widgets
|
||||||
|
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Intent
|
||||||
import org.isoron.uhabits.R
|
import org.isoron.uhabits.R
|
||||||
|
import org.isoron.uhabits.core.models.Habit
|
||||||
|
import org.isoron.uhabits.core.models.Timestamp
|
||||||
|
import org.isoron.uhabits.intents.PendingIntentFactory
|
||||||
import java.lang.IllegalStateException
|
import java.lang.IllegalStateException
|
||||||
|
|
||||||
enum class StackWidgetType(val value: Int) {
|
enum class StackWidgetType(val value: Int) {
|
||||||
@@ -73,5 +78,39 @@ enum class StackWidgetType(val value: Int) {
|
|||||||
else -> throw IllegalStateException()
|
else -> throw IllegalStateException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getPendingIntentTemplate(
|
||||||
|
factory: PendingIntentFactory,
|
||||||
|
widgetType: StackWidgetType,
|
||||||
|
habits: List<Habit>
|
||||||
|
): PendingIntent {
|
||||||
|
val containsNumerical = habits.any { it.isNumerical }
|
||||||
|
return when (widgetType) {
|
||||||
|
CHECKMARK -> if (containsNumerical) {
|
||||||
|
factory.showNumberPickerTemplate()
|
||||||
|
} else {
|
||||||
|
factory.toggleCheckmarkTemplate()
|
||||||
|
}
|
||||||
|
FREQUENCY, SCORE, HISTORY, STREAKS, TARGET -> factory.showHabitTemplate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIntentFillIn(
|
||||||
|
factory: PendingIntentFactory,
|
||||||
|
widgetType: StackWidgetType,
|
||||||
|
habit: Habit,
|
||||||
|
allHabitsInStackWidget: List<Habit>,
|
||||||
|
timestamp: Timestamp
|
||||||
|
): Intent {
|
||||||
|
val containsNumerical = allHabitsInStackWidget.any { it.isNumerical }
|
||||||
|
return when (widgetType) {
|
||||||
|
CHECKMARK -> if (containsNumerical) {
|
||||||
|
factory.showNumberPickerFillIn(habit, timestamp)
|
||||||
|
} else {
|
||||||
|
factory.toggleCheckmarkFillIn(habit, timestamp)
|
||||||
|
}
|
||||||
|
FREQUENCY, SCORE, HISTORY, STREAKS, TARGET -> factory.showHabitFillIn(habit)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,5 +21,4 @@
|
|||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@color/ic_launcher_background"/>
|
<background android:drawable="@color/ic_launcher_background"/>
|
||||||
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
||||||
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
|
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 7.4 KiB |
@@ -43,11 +43,11 @@ kotlin {
|
|||||||
val jvmMain by getting {
|
val jvmMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
compileOnly("com.google.dagger:dagger:2.43.2")
|
compileOnly("com.google.dagger:dagger:2.41")
|
||||||
implementation("com.google.guava:guava:31.1-android")
|
implementation("com.google.guava:guava:31.1-android")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.7.10")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.21")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.1")
|
||||||
implementation("androidx.annotation:annotation:1.4.0")
|
implementation("androidx.annotation:annotation:1.3.0")
|
||||||
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
implementation("com.google.code.findbugs:jsr305:3.0.2")
|
||||||
implementation("com.opencsv:opencsv:5.6")
|
implementation("com.opencsv:opencsv:5.6")
|
||||||
implementation("commons-codec:commons-codec:1.15")
|
implementation("commons-codec:commons-codec:1.15")
|
||||||
@@ -59,7 +59,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("test"))
|
implementation(kotlin("test"))
|
||||||
implementation(kotlin("test-junit"))
|
implementation(kotlin("test-junit"))
|
||||||
implementation("org.xerial:sqlite-jdbc:3.39.2.1")
|
implementation("org.xerial:sqlite-jdbc:3.36.0.3")
|
||||||
implementation("org.hamcrest:hamcrest:2.2")
|
implementation("org.hamcrest:hamcrest:2.2")
|
||||||
implementation("org.apache.commons:commons-io:1.3.2")
|
implementation("org.apache.commons:commons-io:1.3.2")
|
||||||
implementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
implementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
||||||
|
|||||||
@@ -25,6 +25,12 @@ class StringUtils {
|
|||||||
|
|
||||||
fun joinLongs(values: LongArray): String = values.joinToString(separator = ",")
|
fun joinLongs(values: LongArray): String = values.joinToString(separator = ",")
|
||||||
|
|
||||||
fun splitLongs(str: String): LongArray = str.split(",").map { it.toLong() }.toLongArray()
|
fun splitLongs(str: String): LongArray {
|
||||||
|
return try {
|
||||||
|
str.split(",").map { it.toLong() }.toLongArray()
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
LongArray(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ data class FrequencyCardState(
|
|||||||
val firstWeekday: Int,
|
val firstWeekday: Int,
|
||||||
val frequency: HashMap<Timestamp, Array<Int>>,
|
val frequency: HashMap<Timestamp, Array<Int>>,
|
||||||
val theme: Theme,
|
val theme: Theme,
|
||||||
val isNumerical: Boolean
|
|
||||||
)
|
)
|
||||||
|
|
||||||
class FrequencyCardPresenter {
|
class FrequencyCardPresenter {
|
||||||
@@ -41,7 +40,6 @@ class FrequencyCardPresenter {
|
|||||||
theme: Theme
|
theme: Theme
|
||||||
) = FrequencyCardState(
|
) = FrequencyCardState(
|
||||||
color = habit.color,
|
color = habit.color,
|
||||||
isNumerical = habit.isNumerical,
|
|
||||||
frequency = habit.originalEntries.computeWeekdayFrequency(
|
frequency = habit.originalEntries.computeWeekdayFrequency(
|
||||||
isNumerical = habit.isNumerical
|
isNumerical = habit.isNumerical
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ application {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
val ktorVersion = "1.6.8"
|
val ktorVersion = "1.6.8"
|
||||||
val kotlinVersion = "1.7.10"
|
val kotlinVersion = "1.6.21"
|
||||||
val logbackVersion = "1.4.0"
|
val logbackVersion = "1.2.11"
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
|
||||||
implementation("io.ktor:ktor-server-netty:$ktorVersion")
|
implementation("io.ktor:ktor-server-netty:$ktorVersion")
|
||||||
implementation("ch.qos.logback:logback-classic:$logbackVersion")
|
implementation("ch.qos.logback:logback-classic:$logbackVersion")
|
||||||
@@ -43,9 +43,9 @@ dependencies {
|
|||||||
implementation("io.ktor:ktor-html-builder:$ktorVersion")
|
implementation("io.ktor:ktor-html-builder:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-jackson:$ktorVersion")
|
implementation("io.ktor:ktor-jackson:$ktorVersion")
|
||||||
implementation("org.jetbrains:kotlin-css-jvm:1.0.0-pre.148-kotlin-1.4.30")
|
implementation("org.jetbrains:kotlin-css-jvm:1.0.0-pre.148-kotlin-1.4.30")
|
||||||
implementation("io.prometheus:simpleclient:0.16.0")
|
implementation("io.prometheus:simpleclient:0.15.0")
|
||||||
implementation("io.prometheus:simpleclient_httpserver:0.16.0")
|
implementation("io.prometheus:simpleclient_httpserver:0.15.0")
|
||||||
implementation("io.prometheus:simpleclient_hotspot:0.16.0")
|
implementation("io.prometheus:simpleclient_hotspot:0.15.0")
|
||||||
testImplementation("io.ktor:ktor-server-tests:$ktorVersion")
|
testImplementation("io.ktor:ktor-server-tests:$ktorVersion")
|
||||||
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
|
||||||
testImplementation(kotlin("test"))
|
testImplementation(kotlin("test"))
|
||||||
|
|||||||
Reference in New Issue
Block a user