A fork of Simple Time Tracker with WearOS support. (Now integrated upstream)
0

Configure Feed

Select the types of activity you want to include in your feed.

add record time adjustment

razeeman (Jun 25, 2022, 2:17 PM +0300) e8eceb85 a15c8f8a

+301 -4
+14
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/view/ChangeRecordFragment.kt
··· 141 141 (extra as? ChangeRecordParams.Tracked)?.from 142 142 ) 143 143 } 144 + 145 + // TODO add color change on opened 146 + btnChangeRecordTimeStartedAdjust.setOnClick(viewModel::onAdjustTimeStartedClick) 147 + btnChangeRecordTimeEndedAdjust.setOnClick(viewModel::onAdjustTimeEndedClick) 148 + // TODO switch to recycler 149 + // TODO fix item click background overflowing border 150 + tvChangeRecordAdjustTimeNow.setOnClick(viewModel::onAdjustTimeNowClick) 151 + tvChangeRecordAdjustTimeMinusFirst.setOnClick(viewModel::onAdjustTimeMinusFirstClick) 152 + tvChangeRecordAdjustTimeMinusSecond.setOnClick(viewModel::onAdjustTimeMinusSecondClick) 153 + tvChangeRecordAdjustTimeMinusThird.setOnClick(viewModel::onAdjustTimeMinusThirdClick) 154 + tvChangeRecordAdjustTimePlusFirst.setOnClick(viewModel::onAdjustTimePlusFirstClick) 155 + tvChangeRecordAdjustTimePlusSecond.setOnClick(viewModel::onAdjustTimePlusSecondClick) 156 + tvChangeRecordAdjustTimePlusThird.setOnClick(viewModel::onAdjustTimePlusThirdClick) 144 157 } 145 158 146 159 override fun initViewModel() = with(binding) { ··· 180 193 keyboardVisibility.observe { visible -> 181 194 if (visible) showKeyboard(etChangeRecordComment) else hideKeyboard() 182 195 } 196 + timeAdjustmentVisibility.observe(containerChangeRecordTimeAdjust::visible::set) 183 197 } 184 198 with(removeRecordViewModel) { 185 199 prepare((extra as? ChangeRecordParams.Tracked)?.id.orZero())
+123 -2
features/feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordViewModel.kt
··· 32 32 import com.example.util.simpletimetracker.navigation.params.screen.DateTimeDialogParams 33 33 import com.example.util.simpletimetracker.navigation.params.screen.DateTimeDialogType 34 34 import kotlinx.coroutines.launch 35 + import java.util.concurrent.TimeUnit 35 36 import javax.inject.Inject 36 37 37 38 class ChangeRecordViewModel @Inject constructor( ··· 87 88 val saveButtonEnabled: LiveData<Boolean> = MutableLiveData(true) 88 89 val keyboardVisibility: LiveData<Boolean> = MutableLiveData(false) 89 90 val comment: LiveData<String> = MutableLiveData() 91 + val timeAdjustmentVisibility: LiveData<Boolean> by lazy { MutableLiveData(loadTimeAdjustmentVisibility()) } 90 92 91 93 private var newTypeId: Long = 0 92 94 private var newTimeEnded: Long = 0 93 95 private var newTimeStarted: Long = 0 94 96 private var newComment: String = "" 95 97 private var newCategoryIds: MutableList<Long> = mutableListOf() 98 + private var timeAdjustmentState: TimeAdjustmentVisibility = TimeAdjustmentVisibility.HIDDEN 96 99 97 100 fun onTypeChooserClick() { 98 101 (keyboardVisibility as MutableLiveData).value = false ··· 221 224 TIME_STARTED_TAG -> { 222 225 if (timestamp != newTimeStarted) { 223 226 newTimeStarted = timestamp 224 - if (timestamp > newTimeEnded) newTimeEnded = timestamp 227 + checkTimeEnded() 225 228 updatePreview() 226 229 } 227 230 } 228 231 TIME_ENDED_TAG -> { 229 232 if (timestamp != newTimeEnded) { 230 233 newTimeEnded = timestamp 231 - if (timestamp < newTimeStarted) newTimeStarted = timestamp 234 + checkTimeStarted() 232 235 updatePreview() 233 236 } 234 237 } ··· 245 248 } 246 249 } 247 250 251 + fun onAdjustTimeStartedClick() { 252 + when (timeAdjustmentState) { 253 + TimeAdjustmentVisibility.HIDDEN -> { 254 + timeAdjustmentState = TimeAdjustmentVisibility.TIME_STARTED 255 + updateTimeAdjustmentVisibility() 256 + } 257 + TimeAdjustmentVisibility.TIME_STARTED -> { 258 + timeAdjustmentState = TimeAdjustmentVisibility.HIDDEN 259 + updateTimeAdjustmentVisibility() 260 + } 261 + TimeAdjustmentVisibility.TIME_ENDED -> { 262 + timeAdjustmentState = TimeAdjustmentVisibility.HIDDEN 263 + updateTimeAdjustmentVisibility() 264 + // TODO add delay 265 + timeAdjustmentState = TimeAdjustmentVisibility.TIME_STARTED 266 + updateTimeAdjustmentVisibility() 267 + } 268 + } 269 + } 270 + 271 + fun onAdjustTimeEndedClick() { 272 + when (timeAdjustmentState) { 273 + TimeAdjustmentVisibility.HIDDEN -> { 274 + timeAdjustmentState = TimeAdjustmentVisibility.TIME_ENDED 275 + updateTimeAdjustmentVisibility() 276 + } 277 + TimeAdjustmentVisibility.TIME_STARTED -> { 278 + timeAdjustmentState = TimeAdjustmentVisibility.HIDDEN 279 + updateTimeAdjustmentVisibility() 280 + // TODO add delay 281 + timeAdjustmentState = TimeAdjustmentVisibility.TIME_ENDED 282 + updateTimeAdjustmentVisibility() 283 + } 284 + TimeAdjustmentVisibility.TIME_ENDED -> { 285 + timeAdjustmentState = TimeAdjustmentVisibility.HIDDEN 286 + updateTimeAdjustmentVisibility() 287 + } 288 + } 289 + } 290 + 291 + fun onAdjustTimeNowClick() = viewModelScope.launch { 292 + when (timeAdjustmentState) { 293 + TimeAdjustmentVisibility.TIME_STARTED -> { 294 + newTimeStarted = System.currentTimeMillis() 295 + checkTimeEnded() 296 + } 297 + TimeAdjustmentVisibility.TIME_ENDED -> { 298 + newTimeEnded = System.currentTimeMillis() 299 + checkTimeStarted() 300 + } 301 + else -> { 302 + // Do nothing, it's hidden. 303 + } 304 + } 305 + updatePreview() 306 + } 307 + 308 + fun onAdjustTimeMinusFirstClick() { 309 + adjustRecordTime(-30) 310 + } 311 + 312 + fun onAdjustTimeMinusSecondClick() { 313 + adjustRecordTime(-5) 314 + } 315 + 316 + fun onAdjustTimeMinusThirdClick() { 317 + adjustRecordTime(-1) 318 + } 319 + 320 + fun onAdjustTimePlusFirstClick() { 321 + adjustRecordTime(1) 322 + } 323 + 324 + fun onAdjustTimePlusSecondClick() { 325 + adjustRecordTime(5) 326 + } 327 + 328 + fun onAdjustTimePlusThirdClick() { 329 + adjustRecordTime(30) 330 + } 331 + 332 + private fun adjustRecordTime(shiftInMinutes: Long) = viewModelScope.launch { 333 + when (timeAdjustmentState) { 334 + TimeAdjustmentVisibility.TIME_STARTED -> { 335 + newTimeStarted += TimeUnit.MINUTES.toMillis(shiftInMinutes) 336 + checkTimeEnded() 337 + } 338 + TimeAdjustmentVisibility.TIME_ENDED -> { 339 + newTimeEnded += TimeUnit.MINUTES.toMillis(shiftInMinutes) 340 + checkTimeStarted() 341 + } 342 + else -> { 343 + // Do nothing, it's hidden. 344 + } 345 + } 346 + updatePreview() 347 + } 348 + 349 + private fun checkTimeStarted() { 350 + if (newTimeEnded < newTimeStarted) newTimeStarted = newTimeEnded 351 + } 352 + 353 + private fun checkTimeEnded() { 354 + if (newTimeStarted > newTimeEnded) newTimeEnded = newTimeStarted 355 + } 356 + 248 357 private fun getInitialDate(daysFromToday: Int): Long { 249 358 return timeMapper.toTimestampShifted(daysFromToday, RangeLength.Day) 250 359 } ··· 314 423 return changeRecordViewDataInteractor.getLastCommentsViewData(newTypeId) 315 424 } 316 425 426 + private fun updateTimeAdjustmentVisibility() { 427 + timeAdjustmentVisibility.set(loadTimeAdjustmentVisibility()) 428 + } 429 + 430 + private fun loadTimeAdjustmentVisibility(): Boolean { 431 + return timeAdjustmentState != TimeAdjustmentVisibility.HIDDEN 432 + } 433 + 317 434 private fun showMessage(stringResId: Int) { 318 435 val params = ToastParams(message = resourceRepo.getString(stringResId)) 319 436 router.show(params) 437 + } 438 + 439 + private enum class TimeAdjustmentVisibility { 440 + HIDDEN, TIME_STARTED, TIME_ENDED 320 441 } 321 442 322 443 companion object {
+147 -2
features/feature_change_record/src/main/res/layout/change_record_fragment.xml
··· 62 62 android:gravity="center_vertical" 63 63 android:maxLines="1" 64 64 app:autoSizeMaxTextSize="16sp" 65 + app:autoSizeMinTextSize="1sp" 65 66 app:autoSizeTextType="uniform" 66 67 tools:text="15.02.2020 07:35" /> 67 68 ··· 88 89 android:gravity="center_vertical" 89 90 android:maxLines="1" 90 91 app:autoSizeMaxTextSize="16sp" 92 + app:autoSizeMinTextSize="1sp" 91 93 app:autoSizeTextType="uniform" 92 94 tools:text="15.02.2020 11:58" /> 93 95 94 96 </androidx.cardview.widget.CardView> 95 97 98 + <Space 99 + android:id="@+id/spaceChangeRecordTimeStartedEnd" 100 + android:layout_width="10dp" 101 + android:layout_height="wrap_content" 102 + app:layout_constraintStart_toEndOf="@id/fieldChangeRecordTimeStarted" 103 + app:layout_constraintTop_toTopOf="@id/fieldChangeRecordTimeStarted" /> 104 + 105 + <Space 106 + android:id="@+id/spaceChangeRecordTimeStartedTop" 107 + android:layout_width="wrap_content" 108 + android:layout_height="12dp" 109 + app:layout_constraintBottom_toTopOf="@id/fieldChangeRecordTimeStarted" 110 + app:layout_constraintEnd_toEndOf="@id/fieldChangeRecordTimeStarted" /> 111 + 112 + <androidx.cardview.widget.CardView 113 + android:id="@+id/btnChangeRecordTimeStartedAdjust" 114 + android:layout_width="wrap_content" 115 + android:layout_height="wrap_content" 116 + android:foreground="?selectableItemBackground" 117 + app:cardBackgroundColor="?appCardBackgroundColor" 118 + app:cardCornerRadius="8dp" 119 + app:cardElevation="4dp" 120 + app:cardPreventCornerOverlap="false" 121 + app:cardUseCompatPadding="true" 122 + app:layout_constraintEnd_toEndOf="@id/spaceChangeRecordTimeStartedEnd" 123 + app:layout_constraintTop_toTopOf="@id/spaceChangeRecordTimeStartedTop"> 124 + 125 + <androidx.appcompat.widget.AppCompatTextView 126 + android:layout_width="20dp" 127 + android:layout_height="20dp" 128 + android:layout_margin="4dp" 129 + android:gravity="center" 130 + android:text="+/-" 131 + android:textColor="?appTextHintColor" 132 + android:textStyle="bold" 133 + app:autoSizeMinTextSize="1sp" 134 + app:autoSizeTextType="uniform" /> 135 + 136 + </androidx.cardview.widget.CardView> 137 + 138 + <Space 139 + android:id="@+id/spaceChangeRecordTimeEndedEnd" 140 + android:layout_width="10dp" 141 + android:layout_height="wrap_content" 142 + app:layout_constraintStart_toEndOf="@id/fieldChangeRecordTimeEnded" 143 + app:layout_constraintTop_toTopOf="@id/fieldChangeRecordTimeEnded" /> 144 + 145 + <Space 146 + android:id="@+id/spaceChangeRecordTimeEndedTop" 147 + android:layout_width="wrap_content" 148 + android:layout_height="12dp" 149 + app:layout_constraintBottom_toTopOf="@id/fieldChangeRecordTimeEnded" 150 + app:layout_constraintEnd_toEndOf="@id/fieldChangeRecordTimeEnded" /> 151 + 152 + <androidx.cardview.widget.CardView 153 + android:id="@+id/btnChangeRecordTimeEndedAdjust" 154 + android:layout_width="wrap_content" 155 + android:layout_height="wrap_content" 156 + android:foreground="?selectableItemBackground" 157 + app:cardBackgroundColor="?appCardBackgroundColor" 158 + app:cardCornerRadius="8dp" 159 + app:cardElevation="4dp" 160 + app:cardPreventCornerOverlap="false" 161 + app:cardUseCompatPadding="true" 162 + app:layout_constraintEnd_toEndOf="@id/spaceChangeRecordTimeEndedEnd" 163 + app:layout_constraintTop_toTopOf="@id/spaceChangeRecordTimeEndedTop"> 164 + 165 + <androidx.appcompat.widget.AppCompatTextView 166 + android:layout_width="20dp" 167 + android:layout_height="20dp" 168 + android:layout_margin="4dp" 169 + android:gravity="center" 170 + android:text="+/-" 171 + android:textColor="?appTextHintColor" 172 + android:textStyle="bold" 173 + app:autoSizeMinTextSize="1sp" 174 + app:autoSizeTextType="uniform" /> 175 + 176 + </androidx.cardview.widget.CardView> 177 + 178 + <androidx.constraintlayout.widget.ConstraintLayout 179 + android:id="@+id/containerChangeRecordTimeAdjust" 180 + android:layout_width="match_parent" 181 + android:layout_height="wrap_content" 182 + android:layout_marginStart="@dimen/input_field_margin" 183 + android:layout_marginEnd="@dimen/input_field_margin" 184 + android:paddingHorizontal="2dp" 185 + android:visibility="gone" 186 + app:layout_constraintStart_toStartOf="parent" 187 + app:layout_constraintTop_toBottomOf="@id/fieldChangeRecordTimeStarted" 188 + tools:visibility="visible"> 189 + 190 + <androidx.appcompat.widget.AppCompatTextView 191 + android:id="@+id/tvChangeRecordAdjustTimeNow" 192 + style="@style/ButtonTimeAdjustment" 193 + android:text="Now" 194 + app:layout_constraintEnd_toStartOf="@id/tvChangeRecordAdjustTimeMinusFirst" 195 + app:layout_constraintStart_toStartOf="parent" /> 196 + 197 + <androidx.appcompat.widget.AppCompatTextView 198 + android:id="@+id/tvChangeRecordAdjustTimeMinusFirst" 199 + style="@style/ButtonTimeAdjustment" 200 + android:text="-30" 201 + app:layout_constraintEnd_toStartOf="@id/tvChangeRecordAdjustTimeMinusSecond" 202 + app:layout_constraintStart_toEndOf="@id/tvChangeRecordAdjustTimeNow" /> 203 + 204 + <androidx.appcompat.widget.AppCompatTextView 205 + android:id="@+id/tvChangeRecordAdjustTimeMinusSecond" 206 + style="@style/ButtonTimeAdjustment" 207 + android:text="-5" 208 + app:layout_constraintEnd_toStartOf="@id/tvChangeRecordAdjustTimeMinusThird" 209 + app:layout_constraintStart_toEndOf="@id/tvChangeRecordAdjustTimeMinusFirst" /> 210 + 211 + <androidx.appcompat.widget.AppCompatTextView 212 + android:id="@+id/tvChangeRecordAdjustTimeMinusThird" 213 + style="@style/ButtonTimeAdjustment" 214 + android:text="-1" 215 + app:layout_constraintEnd_toStartOf="@id/tvChangeRecordAdjustTimePlusFirst" 216 + app:layout_constraintStart_toEndOf="@id/tvChangeRecordAdjustTimeMinusSecond" /> 217 + 218 + <androidx.appcompat.widget.AppCompatTextView 219 + android:id="@+id/tvChangeRecordAdjustTimePlusFirst" 220 + style="@style/ButtonTimeAdjustment" 221 + android:text="+1" 222 + app:layout_constraintEnd_toStartOf="@id/tvChangeRecordAdjustTimePlusSecond" 223 + app:layout_constraintStart_toEndOf="@id/tvChangeRecordAdjustTimeMinusThird" /> 224 + 225 + <androidx.appcompat.widget.AppCompatTextView 226 + android:id="@+id/tvChangeRecordAdjustTimePlusSecond" 227 + style="@style/ButtonTimeAdjustment" 228 + android:text="+5" 229 + app:layout_constraintEnd_toStartOf="@id/tvChangeRecordAdjustTimePlusThird" 230 + app:layout_constraintStart_toEndOf="@id/tvChangeRecordAdjustTimePlusFirst" /> 231 + 232 + <androidx.appcompat.widget.AppCompatTextView 233 + android:id="@+id/tvChangeRecordAdjustTimePlusThird" 234 + style="@style/ButtonTimeAdjustment" 235 + android:text="+30" 236 + app:layout_constraintEnd_toEndOf="parent" 237 + app:layout_constraintStart_toEndOf="@id/tvChangeRecordAdjustTimePlusSecond" /> 238 + 239 + </androidx.constraintlayout.widget.ConstraintLayout> 240 + 96 241 <androidx.cardview.widget.CardView 97 242 android:id="@+id/fieldChangeRecordType" 98 243 style="@style/InputFieldCard" ··· 103 248 android:layout_marginEnd="4dp" 104 249 app:layout_constraintEnd_toStartOf="@id/fieldChangeRecordCategory" 105 250 app:layout_constraintStart_toStartOf="parent" 106 - app:layout_constraintTop_toBottomOf="@id/fieldChangeRecordTimeStarted"> 251 + app:layout_constraintTop_toBottomOf="@id/containerChangeRecordTimeAdjust"> 107 252 108 253 <androidx.constraintlayout.widget.ConstraintLayout 109 254 android:layout_width="match_parent" ··· 145 290 android:layout_marginEnd="@dimen/input_field_margin" 146 291 app:layout_constraintEnd_toEndOf="parent" 147 292 app:layout_constraintStart_toEndOf="@id/fieldChangeRecordType" 148 - app:layout_constraintTop_toBottomOf="@id/fieldChangeRecordTimeStarted"> 293 + app:layout_constraintTop_toBottomOf="@id/containerChangeRecordTimeAdjust"> 149 294 150 295 <androidx.constraintlayout.widget.ConstraintLayout 151 296 android:layout_width="match_parent"
+1
features/feature_change_running_record/src/main/res/layout/change_running_record_fragment.xml
··· 58 58 android:gravity="center_vertical" 59 59 android:maxLines="1" 60 60 app:autoSizeMaxTextSize="16sp" 61 + app:autoSizeMinTextSize="1sp" 61 62 app:autoSizeTextType="uniform" 62 63 tools:text="15.02.2020 07:35" /> 63 64
+2
features/feature_dialogs/src/main/res/layout/csv_export_settings_fragment.xml
··· 48 48 android:gravity="center_vertical" 49 49 android:maxLines="1" 50 50 app:autoSizeMaxTextSize="16sp" 51 + app:autoSizeMinTextSize="1sp" 51 52 app:autoSizeTextType="uniform" 52 53 tools:text="15.02.2020 07:35" /> 53 54 ··· 74 75 android:gravity="center_vertical" 75 76 android:maxLines="1" 76 77 app:autoSizeMaxTextSize="16sp" 78 + app:autoSizeMinTextSize="1sp" 77 79 app:autoSizeTextType="uniform" 78 80 tools:text="15.02.2020 11:58" /> 79 81
+2
features/feature_dialogs/src/main/res/layout/custom_range_selection_fragment.xml
··· 37 37 android:gravity="center_vertical" 38 38 android:maxLines="1" 39 39 app:autoSizeMaxTextSize="16sp" 40 + app:autoSizeMinTextSize="1sp" 40 41 app:autoSizeTextType="uniform" 41 42 tools:text="15.02.2020 07:35" /> 42 43 ··· 63 64 android:gravity="center_vertical" 64 65 android:maxLines="1" 65 66 app:autoSizeMaxTextSize="16sp" 67 + app:autoSizeMinTextSize="1sp" 66 68 app:autoSizeTextType="uniform" 67 69 tools:text="15.02.2020 11:58" /> 68 70
+12
features/feature_views/src/main/res/values/styles.xml
··· 286 286 <item name="layout_constraintHorizontal_weight">1</item> 287 287 </style> 288 288 289 + <style name="ButtonTimeAdjustment"> 290 + <item name="android:layout_width">0dp</item> 291 + <item name="android:layout_height">28dp</item> 292 + <item name="android:background">?appInputFieldBorder</item> 293 + <item name="android:foreground">?selectableItemBackground</item> 294 + <item name="android:gravity">center</item> 295 + <item name="android:padding">4dp</item> 296 + <item name="android:textColor">?appTextPrimaryColor</item> 297 + <item name="autoSizeMinTextSize">1sp</item> 298 + <item name="autoSizeTextType">uniform</item> 299 + </style> 300 + 289 301 </resources>