mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 01:08:50 -06:00
Clean up kotlin code
* static imports * less nullable types * format
This commit is contained in:
@@ -125,6 +125,7 @@ dependencies {
|
||||
testImplementation "junit:junit:4.12"
|
||||
testImplementation "org.mockito:mockito-core:2.28.2"
|
||||
testImplementation "org.mockito:mockito-inline:2.8.9"
|
||||
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
|
||||
}
|
||||
|
||||
kapt {
|
||||
|
||||
@@ -38,19 +38,13 @@ import org.mockito.Mockito.mock
|
||||
|
||||
@Module
|
||||
class TestModule {
|
||||
@Provides fun ListHabitsBehavior() = mock(ListHabitsBehavior::class.java)
|
||||
@Provides fun listHabitsBehavior(): ListHabitsBehavior = mock(ListHabitsBehavior::class.java)
|
||||
}
|
||||
|
||||
@ActivityScope
|
||||
@Component(
|
||||
modules = arrayOf(
|
||||
ActivityContextModule::class,
|
||||
HabitsActivityModule::class,
|
||||
ListHabitsModule::class,
|
||||
HabitModule::class,
|
||||
TestModule::class
|
||||
),
|
||||
dependencies = arrayOf(HabitsApplicationComponent::class)
|
||||
modules = [ActivityContextModule::class, HabitsActivityModule::class, ListHabitsModule::class, HabitModule::class, TestModule::class],
|
||||
dependencies = [HabitsApplicationComponent::class]
|
||||
)
|
||||
interface HabitsActivityTestComponent {
|
||||
fun getCheckmarkPanelViewFactory(): CheckmarkPanelViewFactory
|
||||
|
||||
@@ -25,7 +25,8 @@ import androidx.test.espresso.UiController
|
||||
import androidx.test.espresso.ViewAction
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.matcher.ViewMatchers
|
||||
import org.hamcrest.CoreMatchers
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.CoreMatchers.endsWith
|
||||
import org.hamcrest.Matcher
|
||||
import org.isoron.uhabits.BaseUserInterfaceTest
|
||||
import org.isoron.uhabits.R
|
||||
@@ -56,12 +57,12 @@ object ListHabitsSteps {
|
||||
|
||||
private fun clickTextInsideOverflowMenu(id: Int) {
|
||||
Espresso.onView(
|
||||
CoreMatchers.allOf(
|
||||
allOf(
|
||||
ViewMatchers.withContentDescription("More options"),
|
||||
ViewMatchers.withParent(
|
||||
ViewMatchers.withParent(
|
||||
ViewMatchers.withClassName(
|
||||
CoreMatchers.endsWith("Toolbar")
|
||||
endsWith("Toolbar")
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -107,9 +108,9 @@ object ListHabitsSteps {
|
||||
fun longPressCheckmarks(habit: String?, count: Int) {
|
||||
CommonSteps.scrollToText(habit)
|
||||
Espresso.onView(
|
||||
CoreMatchers.allOf(
|
||||
allOf(
|
||||
ViewMatchers.hasDescendant(ViewMatchers.withText(habit)),
|
||||
ViewMatchers.withClassName(CoreMatchers.endsWith("HabitCardView"))
|
||||
ViewMatchers.withClassName(endsWith("HabitCardView"))
|
||||
)
|
||||
).perform(
|
||||
longClickDescendantWithClass(CheckmarkButtonView::class.java, count)
|
||||
|
||||
@@ -28,8 +28,8 @@ import org.isoron.uhabits.BaseUserInterfaceTest
|
||||
object WidgetSteps {
|
||||
@Throws(Exception::class)
|
||||
fun clickCheckmarkWidget() {
|
||||
val view_id = "org.isoron.uhabits:id/imageView"
|
||||
BaseUserInterfaceTest.device.findObject(UiSelector().resourceId(view_id)).click()
|
||||
val viewId = "org.isoron.uhabits:id/imageView"
|
||||
BaseUserInterfaceTest.device.findObject(UiSelector().resourceId(viewId)).click()
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
@@ -66,7 +66,7 @@ object WidgetSteps {
|
||||
BaseUserInterfaceTest.device.findObject(UiSelector().description("Apps")).click()
|
||||
BaseUserInterfaceTest.device.findObject(UiSelector().description("Widgets")).click()
|
||||
} else {
|
||||
val list_id = "com.android.launcher3:id/widgets_list_view"
|
||||
val listId = "com.android.launcher3:id/widgets_list_view"
|
||||
BaseUserInterfaceTest.device.pressHome()
|
||||
BaseUserInterfaceTest.device.waitForIdle()
|
||||
BaseUserInterfaceTest.device.drag(w / 2, h / 2, w / 2, h / 2, 8)
|
||||
@@ -76,10 +76,10 @@ object WidgetSteps {
|
||||
}
|
||||
button.click()
|
||||
if (VERSION.SDK_INT >= 28) {
|
||||
UiScrollable(UiSelector().resourceId(list_id))
|
||||
UiScrollable(UiSelector().resourceId(listId))
|
||||
.scrollForward()
|
||||
}
|
||||
UiScrollable(UiSelector().resourceId(list_id))
|
||||
UiScrollable(UiSelector().resourceId(listId))
|
||||
.scrollIntoView(UiSelector().text("Checkmark"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,12 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
private const val PATH = "habits/list/CheckmarkPanelView"
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
@MediumTest
|
||||
class EntryPanelViewTest : BaseViewTest() {
|
||||
|
||||
private val PATH = "habits/list/CheckmarkPanelView"
|
||||
private lateinit var view: CheckmarkPanelView
|
||||
|
||||
@Before
|
||||
@@ -75,27 +76,6 @@ class EntryPanelViewTest : BaseViewTest() {
|
||||
assertRenders(view, "$PATH/render.png")
|
||||
}
|
||||
|
||||
// // Flaky test
|
||||
// @Test
|
||||
// fun testRender_withDifferentColor() {
|
||||
// view.color = PaletteUtils.getAndroidTestColor(1)
|
||||
// assertRenders(view, "$PATH/render_different_color.png")
|
||||
// }
|
||||
|
||||
// // Flaky test
|
||||
// @Test
|
||||
// fun testRender_Reversed() {
|
||||
// prefs.isCheckmarkSequenceReversed = true
|
||||
// assertRenders(view, "$PATH/render_reversed.png")
|
||||
// }
|
||||
|
||||
// // Flaky test
|
||||
// @Test
|
||||
// fun testRender_withOffset() {
|
||||
// view.dataOffset = 3
|
||||
// assertRenders(view, "$PATH/render_offset.png")
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun testToggle() {
|
||||
val timestamps = mutableListOf<Timestamp>()
|
||||
|
||||
@@ -56,7 +56,7 @@ class HabitCardViewTest : BaseViewTest() {
|
||||
view = component.getHabitCardViewFactory().create().apply {
|
||||
habit = habit1
|
||||
values = entries
|
||||
score = habit1.scores.get(today).value
|
||||
score = habit1.scores[today].value
|
||||
isSelected = false
|
||||
buttonCount = 5
|
||||
}
|
||||
|
||||
@@ -73,27 +73,6 @@ class NumberPanelViewTest : BaseViewTest() {
|
||||
assertRenders(view, "$PATH/render.png")
|
||||
}
|
||||
|
||||
// // Flaky test
|
||||
// @Test
|
||||
// fun testRender_withDifferentColor() {
|
||||
// view.color = PaletteUtils.getAndroidTestColor(1)
|
||||
// assertRenders(view, "$PATH/render_different_color.png")
|
||||
// }
|
||||
|
||||
// // Flaky test
|
||||
// @Test
|
||||
// fun testRender_Reversed() {
|
||||
// prefs.isCheckmarkSequenceReversed = true
|
||||
// assertRenders(view, "$PATH/render_reversed.png")
|
||||
// }
|
||||
|
||||
// // Flaky test
|
||||
// @Test
|
||||
// fun testRender_withOffset() {
|
||||
// view.dataOffset = 3
|
||||
// assertRenders(view, "$PATH/render_offset.png")
|
||||
// }
|
||||
|
||||
@Test
|
||||
fun testEdit() {
|
||||
val timestamps = mutableListOf<Timestamp>()
|
||||
|
||||
@@ -103,9 +103,8 @@ class IntentSchedulerTest : BaseAndroidTest() {
|
||||
assertNull(ReminderReceiver.lastReceivedIntent)
|
||||
|
||||
setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46)
|
||||
val intent = ReminderReceiver.lastReceivedIntent
|
||||
assertNotNull(intent)
|
||||
assertThat(parseId(intent?.data!!), equalTo(habit.id))
|
||||
val intent = ReminderReceiver.lastReceivedIntent!!
|
||||
assertThat(parseId(intent.data!!), equalTo(habit.id))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -123,7 +122,6 @@ class IntentSchedulerTest : BaseAndroidTest() {
|
||||
assertNull(WidgetReceiver.lastReceivedIntent)
|
||||
|
||||
setSystemTime("America/Chicago", 2020, JUNE, 2, 22, 46)
|
||||
val intent = WidgetReceiver.lastReceivedIntent
|
||||
assertNotNull(intent)
|
||||
WidgetReceiver.lastReceivedIntent!!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,13 +68,6 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
|
||||
assertRenders(view, PATH + "checked.png");
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testRender_implicitlyChecked() throws IOException
|
||||
// {
|
||||
// view.setCheckmarkValue(Checkmark.YES_AUTO);
|
||||
// view.refresh();
|
||||
// assertRenders(view, PATH + "implicitly_checked.png");
|
||||
// }
|
||||
|
||||
@Test
|
||||
public void testRender_largeSize() throws IOException
|
||||
@@ -83,11 +76,4 @@ public class CheckmarkWidgetViewTest extends BaseViewTest
|
||||
assertRenders(view, PATH + "large_size.png");
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testRender_unchecked() throws IOException
|
||||
// {
|
||||
// view.setCheckmarkValue(Checkmark.NO);
|
||||
// view.refresh();
|
||||
// assertRenders(view, PATH + "unchecked.png");
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import android.util.AttributeSet
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.widget.Scroller
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
||||
/**
|
||||
* An AndroidView that implements scrolling.
|
||||
@@ -71,7 +73,7 @@ class AndroidDataView(
|
||||
dx: Float,
|
||||
dy: Float,
|
||||
): Boolean {
|
||||
if (Math.abs(dx) > Math.abs(dy)) {
|
||||
if (abs(dx) > abs(dy)) {
|
||||
val parent = parent
|
||||
parent?.requestDisallowInterceptTouchEvent(true)
|
||||
}
|
||||
@@ -128,7 +130,7 @@ class AndroidDataView(
|
||||
view?.let { v ->
|
||||
var newDataOffset: Int =
|
||||
scroller.currX / (v.dataColumnWidth * canvas.innerDensity).toInt()
|
||||
newDataOffset = Math.max(0, newDataOffset)
|
||||
newDataOffset = max(0, newDataOffset)
|
||||
if (newDataOffset != v.dataOffset) {
|
||||
v.dataOffset = newDataOffset
|
||||
postInvalidate()
|
||||
|
||||
@@ -42,7 +42,7 @@ class AndroidImage(private val bmp: Bitmap) : Image {
|
||||
}
|
||||
}
|
||||
|
||||
public fun Color.toInt(): Int {
|
||||
fun Color.toInt(): Int {
|
||||
return android.graphics.Color.argb(
|
||||
(255 * this.alpha).roundToInt(),
|
||||
(255 * this.red).roundToInt(),
|
||||
|
||||
@@ -83,7 +83,7 @@ class HabitsApplication : Application() {
|
||||
notificationTray.startListening()
|
||||
|
||||
val prefs = component.preferences
|
||||
prefs.setLastAppVersion(BuildConfig.VERSION_CODE)
|
||||
prefs.lastAppVersion = BuildConfig.VERSION_CODE
|
||||
|
||||
val taskRunner = component.taskRunner
|
||||
taskRunner.execute {
|
||||
@@ -106,11 +106,11 @@ class HabitsApplication : Application() {
|
||||
lateinit var component: HabitsApplicationComponent
|
||||
|
||||
fun isTestMode(): Boolean {
|
||||
try {
|
||||
return try {
|
||||
Class.forName("org.isoron.uhabits.BaseAndroidTest")
|
||||
return true
|
||||
true
|
||||
} catch (e: ClassNotFoundException) {
|
||||
return false
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
|
||||
import org.isoron.uhabits.inject.ActivityContext
|
||||
import org.isoron.uhabits.utils.InterfaceUtils
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToLong
|
||||
|
||||
class NumberPickerFactory
|
||||
@Inject constructor(
|
||||
@@ -52,7 +53,7 @@ class NumberPickerFactory
|
||||
val picker2 = view.findViewById<NumberPicker>(R.id.picker2)
|
||||
val tvUnit = view.findViewById<TextView>(R.id.tvUnit)
|
||||
|
||||
val intValue = Math.round(value * 100).toInt()
|
||||
val intValue = (value * 100).roundToLong().toInt()
|
||||
|
||||
picker.minValue = 0
|
||||
picker.maxValue = Integer.MAX_VALUE / 100
|
||||
@@ -86,13 +87,12 @@ class NumberPickerFactory
|
||||
}
|
||||
|
||||
InterfaceUtils.setupEditorAction(
|
||||
picker,
|
||||
TextView.OnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE)
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
|
||||
false
|
||||
}
|
||||
)
|
||||
picker
|
||||
) { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE)
|
||||
dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick()
|
||||
false
|
||||
}
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
@@ -56,8 +56,7 @@ class TaskProgressBar(
|
||||
|
||||
fun update() {
|
||||
val callback = {
|
||||
val activeTaskCount = runner.activeTaskCount
|
||||
val newVisibility = when (activeTaskCount) {
|
||||
val newVisibility = when (runner.activeTaskCount) {
|
||||
0 -> GONE
|
||||
else -> VISIBLE
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class HabitTypeDialog : AppCompatDialogFragment() {
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
): View {
|
||||
val binding = SelectHabitTypeBinding.inflate(inflater, container, false)
|
||||
|
||||
binding.buttonYesNo.setOnClickListener {
|
||||
|
||||
@@ -48,9 +48,9 @@ import org.isoron.uhabits.utils.dim
|
||||
import org.isoron.uhabits.utils.dp
|
||||
import org.isoron.uhabits.utils.setupToolbar
|
||||
import org.isoron.uhabits.utils.sres
|
||||
import java.lang.Math.max
|
||||
import java.lang.Math.min
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
const val MAX_CHECKMARK_COUNT = 60
|
||||
|
||||
|
||||
@@ -39,12 +39,10 @@ class HabitCardListController @Inject constructor(
|
||||
private val selectionMenu: Lazy<ListHabitsSelectionMenu>
|
||||
) : HabitCardListView.Controller, ModelObservable.Listener {
|
||||
|
||||
private val NORMAL_MODE = NormalMode()
|
||||
private val SELECTION_MODE = SelectionMode()
|
||||
private var activeMode: Mode
|
||||
|
||||
init {
|
||||
this.activeMode = NORMAL_MODE
|
||||
this.activeMode = NormalMode()
|
||||
adapter.observable.addListener(this)
|
||||
}
|
||||
|
||||
@@ -83,9 +81,9 @@ class HabitCardListController @Inject constructor(
|
||||
activeMode.startDrag(position)
|
||||
}
|
||||
|
||||
protected fun toggleSelection(position: Int) {
|
||||
private fun toggleSelection(position: Int) {
|
||||
adapter.toggleSelection(position)
|
||||
activeMode = if (adapter.isSelectionEmpty) NORMAL_MODE else SELECTION_MODE
|
||||
activeMode = if (adapter.isSelectionEmpty) NormalMode() else SelectionMode()
|
||||
}
|
||||
|
||||
private fun cancelSelection() {
|
||||
@@ -116,8 +114,7 @@ class HabitCardListController @Inject constructor(
|
||||
*/
|
||||
internal inner class NormalMode : Mode {
|
||||
override fun onItemClick(position: Int) {
|
||||
val habit = adapter.getItem(position)
|
||||
if (habit == null) return
|
||||
val habit = adapter.getItem(position) ?: return
|
||||
behavior.onClickHabit(habit)
|
||||
}
|
||||
|
||||
@@ -130,9 +127,9 @@ class HabitCardListController @Inject constructor(
|
||||
startSelection(position)
|
||||
}
|
||||
|
||||
protected fun startSelection(position: Int) {
|
||||
private fun startSelection(position: Int) {
|
||||
toggleSelection(position)
|
||||
activeMode = SELECTION_MODE
|
||||
activeMode = SelectionMode()
|
||||
selectionMenu.get().onSelectionStart()
|
||||
}
|
||||
}
|
||||
@@ -158,8 +155,8 @@ class HabitCardListController @Inject constructor(
|
||||
notifyListener()
|
||||
}
|
||||
|
||||
protected fun notifyListener() {
|
||||
if (activeMode === SELECTION_MODE)
|
||||
private fun notifyListener() {
|
||||
if (activeMode === SelectionMode())
|
||||
selectionMenu.get().onSelectionChange()
|
||||
else
|
||||
selectionMenu.get().onSelectionFinish()
|
||||
|
||||
@@ -170,22 +170,22 @@ class HabitCardListView(
|
||||
inner class TouchHelperCallback : ItemTouchHelper.Callback() {
|
||||
override fun getMovementFlags(
|
||||
recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder
|
||||
viewHolder: ViewHolder
|
||||
): Int {
|
||||
return makeMovementFlags(UP or DOWN, START or END)
|
||||
}
|
||||
|
||||
override fun onMove(
|
||||
recyclerView: RecyclerView,
|
||||
from: RecyclerView.ViewHolder,
|
||||
to: RecyclerView.ViewHolder
|
||||
from: ViewHolder,
|
||||
to: ViewHolder
|
||||
): Boolean {
|
||||
controller.get().drop(from.adapterPosition, to.adapterPosition)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onSwiped(
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
viewHolder: ViewHolder,
|
||||
direction: Int
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ class HabitCardViewFactory
|
||||
|
||||
class HabitCardView(
|
||||
@ActivityContext context: Context,
|
||||
private val checkmarkPanelFactory: CheckmarkPanelViewFactory,
|
||||
private val numberPanelFactory: NumberPanelViewFactory,
|
||||
checkmarkPanelFactory: CheckmarkPanelViewFactory,
|
||||
numberPanelFactory: NumberPanelViewFactory,
|
||||
private val behavior: ListHabitsBehavior
|
||||
) : FrameLayout(context),
|
||||
ModelObservable.Listener {
|
||||
@@ -174,7 +174,7 @@ class HabitCardView(
|
||||
}
|
||||
|
||||
clipToPadding = false
|
||||
layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
||||
layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
|
||||
val margin = dp(3f).toInt()
|
||||
setPadding(margin, 0, margin, margin)
|
||||
addView(innerFrame)
|
||||
|
||||
@@ -71,7 +71,7 @@ class NumberPanelView(
|
||||
setupButtons()
|
||||
}
|
||||
|
||||
override fun createButton() = buttonFactory.create()!!
|
||||
override fun createButton() = buttonFactory.create()
|
||||
|
||||
@Synchronized
|
||||
override fun setupButtons() {
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
|
||||
import org.isoron.uhabits.databinding.ShowHabitOverviewBinding
|
||||
import org.isoron.uhabits.utils.StyledResources
|
||||
import org.isoron.uhabits.utils.toThemedAndroidColor
|
||||
import kotlin.math.abs
|
||||
|
||||
class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
|
||||
|
||||
@@ -36,7 +37,7 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
|
||||
return String.format(
|
||||
"%s%.0f%%",
|
||||
if (percentageDiff >= 0) "+" else "\u2212",
|
||||
Math.abs(percentageDiff) * 100
|
||||
abs(percentageDiff) * 100
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class SyncActivity : AppCompatActivity(), SyncBehavior.Screen {
|
||||
title = resources.getString(R.string.device_sync),
|
||||
)
|
||||
binding.syncLink.setOnClickListener { copyToClipboard() }
|
||||
binding.instructions.setText(Html.fromHtml(resources.getString(R.string.sync_instructions)))
|
||||
binding.instructions.text = Html.fromHtml(resources.getString(R.string.sync_instructions))
|
||||
setContentView(binding.root)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,22 +27,22 @@ class AndroidCursor(private val cursor: android.database.Cursor) : Cursor {
|
||||
override fun moveToNext() = cursor.moveToNext()
|
||||
|
||||
override fun getInt(index: Int): Int? {
|
||||
if (cursor.isNull(index)) return null
|
||||
else return cursor.getInt(index)
|
||||
return if (cursor.isNull(index)) null
|
||||
else cursor.getInt(index)
|
||||
}
|
||||
|
||||
override fun getLong(index: Int): Long? {
|
||||
if (cursor.isNull(index)) return null
|
||||
else return cursor.getLong(index)
|
||||
return if (cursor.isNull(index)) null
|
||||
else cursor.getLong(index)
|
||||
}
|
||||
|
||||
override fun getDouble(index: Int): Double? {
|
||||
if (cursor.isNull(index)) return null
|
||||
else return cursor.getDouble(index)
|
||||
return if (cursor.isNull(index)) null
|
||||
else cursor.getDouble(index)
|
||||
}
|
||||
|
||||
override fun getString(index: Int): String? {
|
||||
if (cursor.isNull(index)) return null
|
||||
else return cursor.getString(index)
|
||||
return if (cursor.isNull(index)) null
|
||||
else cursor.getString(index)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class AndroidDatabase(
|
||||
return db.update(tableName, contValues, where, params)
|
||||
}
|
||||
|
||||
override fun insert(tableName: String, values: Map<String, Any?>): Long? {
|
||||
override fun insert(tableName: String, values: Map<String, Any?>): Long {
|
||||
val contValues = mapToContentValues(values)
|
||||
return db.insert(tableName, null, contValues)
|
||||
}
|
||||
|
||||
@@ -32,13 +32,8 @@ import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
|
||||
|
||||
@ActivityScope
|
||||
@Component(
|
||||
modules = arrayOf(
|
||||
ActivityContextModule::class,
|
||||
HabitsActivityModule::class,
|
||||
ListHabitsModule::class,
|
||||
HabitModule::class
|
||||
),
|
||||
dependencies = arrayOf(HabitsApplicationComponent::class)
|
||||
modules = [ActivityContextModule::class, HabitsActivityModule::class, ListHabitsModule::class, HabitModule::class],
|
||||
dependencies = [HabitsApplicationComponent::class]
|
||||
)
|
||||
interface HabitsActivityComponent {
|
||||
val colorPickerDialogFactory: ColorPickerDialogFactory
|
||||
|
||||
@@ -44,9 +44,8 @@ class IntentParser
|
||||
}
|
||||
|
||||
private fun parseHabit(uri: Uri): Habit {
|
||||
val habit = habits.getById(parseId(uri))
|
||||
return habits.getById(parseId(uri))
|
||||
?: throw IllegalArgumentException("habit not found")
|
||||
return habit
|
||||
}
|
||||
|
||||
private fun parseTimestamp(intent: Intent): Timestamp {
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.isoron.uhabits.core.utils.DateFormats
|
||||
import org.isoron.uhabits.inject.AppContext
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.min
|
||||
|
||||
@AppScope
|
||||
class IntentScheduler
|
||||
@@ -84,7 +85,7 @@ class IntentScheduler
|
||||
}
|
||||
|
||||
private fun logReminderScheduled(habit: Habit, reminderTime: Long) {
|
||||
val min = Math.min(5, habit.name.length)
|
||||
val min = min(5, habit.name.length)
|
||||
val name = habit.name.substring(0, min)
|
||||
val df = DateFormats.getBackupDateFormat()
|
||||
val time = df.format(Date(reminderTime))
|
||||
|
||||
@@ -41,7 +41,7 @@ class PendingIntentFactory
|
||||
) {
|
||||
|
||||
fun addCheckmark(habit: Habit, timestamp: Timestamp?): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
1,
|
||||
Intent(context, WidgetReceiver::class.java).apply {
|
||||
@@ -53,7 +53,7 @@ class PendingIntentFactory
|
||||
)
|
||||
|
||||
fun dismissNotification(habit: Habit): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
0,
|
||||
Intent(context, ReminderReceiver::class.java).apply {
|
||||
@@ -64,7 +64,7 @@ class PendingIntentFactory
|
||||
)
|
||||
|
||||
fun removeRepetition(habit: Habit): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
3,
|
||||
Intent(context, WidgetReceiver::class.java).apply {
|
||||
@@ -90,7 +90,7 @@ class PendingIntentFactory
|
||||
reminderTime: Long?,
|
||||
timestamp: Long
|
||||
): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
(habit.id!! % Integer.MAX_VALUE).toInt() + 1,
|
||||
Intent(context, ReminderReceiver::class.java).apply {
|
||||
@@ -103,7 +103,7 @@ class PendingIntentFactory
|
||||
)
|
||||
|
||||
fun snoozeNotification(habit: Habit): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
0,
|
||||
Intent(context, ReminderReceiver::class.java).apply {
|
||||
@@ -114,7 +114,7 @@ class PendingIntentFactory
|
||||
)
|
||||
|
||||
fun toggleCheckmark(habit: Habit, timestamp: Long?): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
2,
|
||||
Intent(context, WidgetReceiver::class.java).apply {
|
||||
@@ -145,7 +145,7 @@ class PendingIntentFactory
|
||||
)
|
||||
|
||||
fun updateWidgets(): PendingIntent =
|
||||
PendingIntent.getBroadcast(
|
||||
getBroadcast(
|
||||
context,
|
||||
0,
|
||||
Intent(context, WidgetReceiver::class.java).apply {
|
||||
|
||||
@@ -40,17 +40,17 @@ class RingtoneManager
|
||||
PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
fun getName(): String? {
|
||||
try {
|
||||
return try {
|
||||
var ringtoneName = context.resources.getString(R.string.none)
|
||||
val ringtoneUri = getURI()
|
||||
if (ringtoneUri != null) {
|
||||
val ringtone = getRingtone(context, ringtoneUri)
|
||||
if (ringtone != null) ringtoneName = ringtone.getTitle(context)
|
||||
}
|
||||
return ringtoneName
|
||||
ringtoneName
|
||||
} catch (e: RuntimeException) {
|
||||
e.printStackTrace()
|
||||
return null
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,8 +80,7 @@ class RemoteSyncServer(
|
||||
try {
|
||||
val url = "${preferences.syncBaseURL}/db/$key"
|
||||
Log.i("RemoteSyncServer", "GET $url")
|
||||
val data: SyncData = httpClient.get(url)
|
||||
return@IO data
|
||||
return@IO httpClient.get<SyncData>(url)
|
||||
} catch (e: ServerResponseException) {
|
||||
throw ServiceUnavailable()
|
||||
} catch (e: ClientRequestException) {
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.content.Context
|
||||
class CheckmarkWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return CheckmarkWidget(context, id, habits[0])
|
||||
else return StackWidget(context, id, StackWidgetType.CHECKMARK, habits)
|
||||
return if (habits.size == 1) CheckmarkWidget(context, id, habits[0])
|
||||
else StackWidget(context, id, StackWidgetType.CHECKMARK, habits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class FrequencyWidget(
|
||||
override val defaultHeight: Int = 200
|
||||
override val defaultWidth: Int = 200
|
||||
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent =
|
||||
pendingIntentFactory.showHabit(habit)
|
||||
|
||||
override fun refreshData(v: View) {
|
||||
|
||||
@@ -24,12 +24,12 @@ import android.content.Context
|
||||
class FrequencyWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return FrequencyWidget(
|
||||
return if (habits.size == 1) FrequencyWidget(
|
||||
context,
|
||||
id,
|
||||
habits[0],
|
||||
preferences!!.firstWeekdayInt
|
||||
preferences.firstWeekdayInt
|
||||
)
|
||||
else return StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
|
||||
else StackWidget(context, id, StackWidgetType.FREQUENCY, habits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class HistoryWidget(
|
||||
override val defaultHeight: Int = 250
|
||||
override val defaultWidth: Int = 250
|
||||
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent? {
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent {
|
||||
return pendingIntentFactory.showHabit(habit)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,11 @@ import android.content.Context
|
||||
class HistoryWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return HistoryWidget(
|
||||
return if (habits.size == 1) HistoryWidget(
|
||||
context,
|
||||
id,
|
||||
habits[0]
|
||||
)
|
||||
else return StackWidget(context, id, StackWidgetType.HISTORY, habits)
|
||||
else StackWidget(context, id, StackWidgetType.HISTORY, habits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class ScoreWidget(
|
||||
override val defaultHeight: Int = 300
|
||||
override val defaultWidth: Int = 300
|
||||
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent =
|
||||
pendingIntentFactory.showHabit(habit)
|
||||
|
||||
override fun refreshData(view: View) {
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.content.Context
|
||||
class ScoreWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return ScoreWidget(context, id, habits[0])
|
||||
else return StackWidget(context, id, StackWidgetType.SCORE, habits)
|
||||
return if (habits.size == 1) ScoreWidget(context, id, habits[0])
|
||||
else StackWidget(context, id, StackWidgetType.SCORE, habits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,10 @@ class StackWidgetService : RemoteViewsService() {
|
||||
|
||||
internal class StackRemoteViewsFactory(private val context: Context, intent: Intent) :
|
||||
RemoteViewsFactory {
|
||||
private val widgetId: Int
|
||||
private val widgetId: Int = intent.getIntExtra(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID
|
||||
)
|
||||
private val habitIds: LongArray
|
||||
private val widgetType: StackWidgetType?
|
||||
private var remoteViews = ArrayList<RemoteViews>()
|
||||
@@ -148,15 +151,11 @@ internal class StackRemoteViewsFactory(private val context: Context, intent: Int
|
||||
}
|
||||
|
||||
init {
|
||||
widgetId = intent.getIntExtra(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID
|
||||
)
|
||||
val widgetTypeValue = intent.getIntExtra(StackWidgetService.WIDGET_TYPE, -1)
|
||||
val habitIdsStr = intent.getStringExtra(StackWidgetService.HABIT_IDS)
|
||||
if (widgetTypeValue < 0) throw RuntimeException("invalid widget type")
|
||||
if (habitIdsStr == null) throw RuntimeException("habitIdsStr is null")
|
||||
widgetType = StackWidgetType.Companion.getWidgetTypeFromValue(widgetTypeValue)
|
||||
widgetType = StackWidgetType.getWidgetTypeFromValue(widgetTypeValue)
|
||||
habitIds = splitLongs(habitIdsStr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class StreakWidget(
|
||||
override val defaultHeight: Int = 200
|
||||
override val defaultWidth: Int = 200
|
||||
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent =
|
||||
pendingIntentFactory.showHabit(habit)
|
||||
|
||||
override fun refreshData(view: View) {
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.content.Context
|
||||
class StreakWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return StreakWidget(context, id, habits[0])
|
||||
else return StackWidget(context, id, StackWidgetType.STREAKS, habits)
|
||||
return if (habits.size == 1) StreakWidget(context, id, habits[0])
|
||||
else StackWidget(context, id, StackWidgetType.STREAKS, habits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ class TargetWidget(
|
||||
override val defaultHeight: Int = 200
|
||||
override val defaultWidth: Int = 200
|
||||
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent? =
|
||||
override fun getOnClickPendingIntent(context: Context): PendingIntent =
|
||||
pendingIntentFactory.showHabit(habit)
|
||||
|
||||
override fun refreshData(view: View) = runBlocking {
|
||||
|
||||
@@ -23,7 +23,7 @@ import android.content.Context
|
||||
class TargetWidgetProvider : BaseWidgetProvider() {
|
||||
override fun getWidgetFromId(context: Context, id: Int): BaseWidget {
|
||||
val habits = getHabitsFromWidgetId(id)
|
||||
if (habits.size == 1) return TargetWidget(context, id, habits[0])
|
||||
else return StackWidget(context, id, StackWidgetType.TARGET, habits)
|
||||
return if (habits.size == 1) TargetWidget(context, id, habits[0])
|
||||
else StackWidget(context, id, StackWidgetType.TARGET, habits)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,14 +37,15 @@ import org.isoron.uhabits.inject.HabitsApplicationComponent
|
||||
import org.isoron.uhabits.utils.InterfaceUtils.getDimension
|
||||
import org.isoron.uhabits.utils.PaletteUtils.getAndroidTestColor
|
||||
import org.isoron.uhabits.utils.StyledResources
|
||||
import kotlin.math.min
|
||||
|
||||
class CheckmarkWidgetView : HabitWidgetView {
|
||||
var activeColor: Int = 0
|
||||
|
||||
var percentage = 0f
|
||||
var name: String? = null
|
||||
protected lateinit var ring: RingView
|
||||
protected lateinit var label: TextView
|
||||
private lateinit var ring: RingView
|
||||
private lateinit var label: TextView
|
||||
var entryValue = 0
|
||||
var entryState = 0
|
||||
var isNumerical = false
|
||||
@@ -92,7 +93,7 @@ class CheckmarkWidgetView : HabitWidgetView {
|
||||
postInvalidate()
|
||||
}
|
||||
|
||||
protected val text: String
|
||||
private val text: String
|
||||
get() = if (isNumerical) {
|
||||
(entryValue / 1000.0).toShortString()
|
||||
} else when (entryState) {
|
||||
@@ -122,7 +123,7 @@ class CheckmarkWidgetView : HabitWidgetView {
|
||||
val height = MeasureSpec.getSize(heightMeasureSpec)
|
||||
var w = width.toFloat()
|
||||
var h = width * 1.25f
|
||||
val scale = Math.min(width / w, height / h)
|
||||
val scale = min(width / w, height / h)
|
||||
w *= scale
|
||||
h *= scale
|
||||
if (h < getDimension(context, R.dimen.checkmarkWidget_heightBreakpoint)) ring.visibility =
|
||||
@@ -131,7 +132,7 @@ class CheckmarkWidgetView : HabitWidgetView {
|
||||
heightMeasureSpec = MeasureSpec.makeMeasureSpec(h.toInt(), MeasureSpec.EXACTLY)
|
||||
var textSize = 0.15f * h
|
||||
val maxTextSize = getDimension(context, R.dimen.smallerTextSize)
|
||||
textSize = Math.min(textSize, maxTextSize)
|
||||
textSize = min(textSize, maxTextSize)
|
||||
label.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize)
|
||||
ring.setTextSize(textSize)
|
||||
ring.setThickness(0.15f * textSize)
|
||||
@@ -139,8 +140,7 @@ class CheckmarkWidgetView : HabitWidgetView {
|
||||
}
|
||||
|
||||
private fun init() {
|
||||
val appComponent: HabitsApplicationComponent
|
||||
appComponent = (context.applicationContext as HabitsApplication).component
|
||||
val appComponent: HabitsApplicationComponent = (context.applicationContext as HabitsApplication).component
|
||||
preferences = appComponent.preferences
|
||||
ring = findViewById<View>(R.id.scoreRing) as RingView
|
||||
label = findViewById<View>(R.id.label) as TextView
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.isoron.uhabits.R
|
||||
import org.isoron.uhabits.utils.InterfaceUtils.dpToPixels
|
||||
import org.isoron.uhabits.utils.StyledResources
|
||||
import java.util.Arrays
|
||||
import kotlin.math.max
|
||||
|
||||
abstract class HabitWidgetView : FrameLayout {
|
||||
protected var background: InsetDrawable? = null
|
||||
@@ -73,7 +74,7 @@ abstract class HabitWidgetView : FrameLayout {
|
||||
Arrays.fill(radii, cornerRadius)
|
||||
val shape = RoundRectShape(radii, null, null)
|
||||
val innerDrawable = ShapeDrawable(shape)
|
||||
val insetLeftTop = Math.max(shadowRadius - shadowOffset, 0)
|
||||
val insetLeftTop = max(shadowRadius - shadowOffset, 0)
|
||||
val insetRightBottom = shadowRadius + shadowOffset
|
||||
background = InsetDrawable(
|
||||
innerDrawable,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.isoron.uhabits
|
||||
|
||||
import com.nhaarman.mockitokotlin2.spy
|
||||
import org.isoron.uhabits.core.commands.CommandRunner
|
||||
import org.isoron.uhabits.core.models.HabitList
|
||||
import org.isoron.uhabits.core.models.memory.MemoryModelFactory
|
||||
@@ -29,7 +30,6 @@ import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.junit.MockitoJUnitRunner
|
||||
|
||||
@RunWith(MockitoJUnitRunner::class)
|
||||
@@ -46,7 +46,7 @@ open class BaseAndroidJVMTest {
|
||||
setFixedLocalTime(fixedLocalTime)
|
||||
setStartDayOffset(0, 0)
|
||||
modelFactory = MemoryModelFactory()
|
||||
habitList = Mockito.spy(modelFactory.buildHabitList())
|
||||
habitList = spy(modelFactory.buildHabitList())
|
||||
fixtures = HabitFixtures(modelFactory, habitList)
|
||||
taskRunner = SingleThreadTaskRunner()
|
||||
commandRunner = CommandRunner(taskRunner)
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
*/
|
||||
package org.isoron.uhabits.receivers
|
||||
|
||||
import com.nhaarman.mockitokotlin2.mock
|
||||
import com.nhaarman.mockitokotlin2.verify
|
||||
import com.nhaarman.mockitokotlin2.verifyNoMoreInteractions
|
||||
import org.isoron.uhabits.BaseAndroidJVMTest
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import org.isoron.uhabits.core.models.Timestamp
|
||||
@@ -25,7 +28,6 @@ import org.isoron.uhabits.core.preferences.Preferences
|
||||
import org.isoron.uhabits.core.reminders.ReminderScheduler
|
||||
import org.isoron.uhabits.core.ui.NotificationTray
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito
|
||||
|
||||
class ReminderControllerTest : BaseAndroidJVMTest() {
|
||||
private lateinit var controller: ReminderController
|
||||
@@ -34,9 +36,9 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
|
||||
private lateinit var preferences: Preferences
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
reminderScheduler = Mockito.mock(ReminderScheduler::class.java)
|
||||
notificationTray = Mockito.mock(NotificationTray::class.java)
|
||||
preferences = Mockito.mock(Preferences::class.java)
|
||||
reminderScheduler = mock()
|
||||
notificationTray = mock()
|
||||
preferences = mock()
|
||||
controller = ReminderController(
|
||||
reminderScheduler,
|
||||
notificationTray,
|
||||
@@ -47,24 +49,24 @@ class ReminderControllerTest : BaseAndroidJVMTest() {
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnDismiss() {
|
||||
Mockito.verifyNoMoreInteractions(reminderScheduler)
|
||||
Mockito.verifyNoMoreInteractions(notificationTray)
|
||||
Mockito.verifyNoMoreInteractions(preferences)
|
||||
verifyNoMoreInteractions(reminderScheduler)
|
||||
verifyNoMoreInteractions(notificationTray)
|
||||
verifyNoMoreInteractions(preferences)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnShowReminder() {
|
||||
val habit = Mockito.mock(Habit::class.java)
|
||||
val habit: Habit = mock()
|
||||
controller.onShowReminder(habit, Timestamp.ZERO.plus(100), 456)
|
||||
Mockito.verify(notificationTray).show(habit, Timestamp.ZERO.plus(100), 456)
|
||||
Mockito.verify(reminderScheduler).scheduleAll()
|
||||
verify(notificationTray).show(habit, Timestamp.ZERO.plus(100), 456)
|
||||
verify(reminderScheduler).scheduleAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnBootCompleted() {
|
||||
controller.onBootCompleted()
|
||||
Mockito.verify(reminderScheduler).scheduleAll()
|
||||
verify(reminderScheduler).scheduleAll()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user