├── .all_custom_gradle_tasks ├── Android App.run.xml ├── Browser Dev Run.run.xml ├── Browser Prod Build.run.xml ├── Code Analysis.run.xml ├── Desktop App.run.xml └── Unit Tests.run.xml ├── .githooks └── pre-commit ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── ci-cd-pipeline.yml │ └── code-check-pipeline.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── android ├── app │ ├── .gitignore │ ├── benchmark-rules.pro │ ├── build.gradle.kts │ ├── proguard-rules.pro │ ├── release │ │ └── output-metadata.json │ └── src │ │ ├── androidTest │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── ExampleInstrumentedTest.kt │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── baseline-prof.txt │ │ ├── ic_launcher-playstore.png │ │ ├── kotlin │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ ├── CoilImageLoader.kt │ │ │ │ ├── ReluctApplication.kt │ │ │ │ └── ui │ │ │ │ ├── MainActivity.kt │ │ │ │ └── ReluctMainCompose.kt │ │ └── res │ │ │ ├── drawable │ │ │ ├── branding_image.xml │ │ │ ├── branding_image_layer_list.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ ├── mono_chrome_icon.xml │ │ │ ├── shape_shifter_icon.xml │ │ │ ├── splash_icon_anim.xml │ │ │ └── vectordrawable.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── values-night-v31 │ │ │ └── splash_theme.xml │ │ │ ├── values-night │ │ │ ├── colors.xml │ │ │ ├── splash_theme.xml │ │ │ └── themes.xml │ │ │ ├── values-v27 │ │ │ └── themes.xml │ │ │ ├── values-v31 │ │ │ └── splash_theme.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── splash_theme.xml │ │ │ ├── strings.xml │ │ │ └── themes.xml │ │ └── test │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── ExampleUnitTest.kt ├── benchmark │ ├── .gitignore │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── android │ │ └── benchmark │ │ ├── ExampleStartupBenchmark.kt │ │ ├── baselineProfile │ │ ├── BaselineProfileGenerator.kt │ │ └── ColdStartupBenchmark.kt │ │ └── util │ │ └── UiDeviceHelpers.kt ├── navigation │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── android │ │ │ └── navigation │ │ │ ├── navbar │ │ │ ├── NavBarElevation.kt │ │ │ ├── NavbarDestinations.kt │ │ │ └── ReluctBottomNavBar.kt │ │ │ ├── navhost │ │ │ ├── AppNavHost.kt │ │ │ └── graphs │ │ │ │ ├── dashboard │ │ │ │ └── DashboardNavHost.kt │ │ │ │ ├── extras │ │ │ │ └── OtherScreensNavGraph.kt │ │ │ │ ├── goals │ │ │ │ ├── GoalDataNavGraph.kt │ │ │ │ └── GoalsNavHost.kt │ │ │ │ ├── screentime │ │ │ │ ├── AppScreenTimeStatsNavGraph.kt │ │ │ │ └── ScreenTimeNavHost.kt │ │ │ │ └── tasks │ │ │ │ └── TasksNavHost.kt │ │ │ ├── toptabs │ │ │ ├── TabDestination.kt │ │ │ ├── dashboard │ │ │ │ ├── DashboardTabBar.kt │ │ │ │ └── DashboardTabDestination.kt │ │ │ ├── goals │ │ │ │ ├── GoalsTabBar.kt │ │ │ │ └── GoalsTabDestination.kt │ │ │ ├── screentime │ │ │ │ ├── ScreenTimeTabBar.kt │ │ │ │ └── ScreenTimeTabDestination.kt │ │ │ └── tasks │ │ │ │ ├── TasksTabBar.kt │ │ │ │ └── TasksTabDestination.kt │ │ │ ├── transitions │ │ │ └── Transitions.kt │ │ │ └── util │ │ │ ├── NavHelpers.kt │ │ │ └── SettingsCheck.kt │ │ └── res │ │ └── values │ │ └── strings.xml ├── screens │ ├── build.gradle.kts │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── android │ │ │ └── screens │ │ │ ├── authentication │ │ │ ├── AuthenticationScreen.kt │ │ │ ├── AuthenticationScreenUI.kt │ │ │ └── pages │ │ │ │ ├── LoginPage.kt │ │ │ │ ├── SignupPage.kt │ │ │ │ └── VerifyEmailPage.kt │ │ │ ├── dashboard │ │ │ ├── components │ │ │ │ └── GetPieChartSlices.kt │ │ │ ├── overview │ │ │ │ ├── DashboardOverviewScreen.kt │ │ │ │ └── DashboardOverviewUI.kt │ │ │ └── statistics │ │ │ │ ├── DashboardStatsScreen.kt │ │ │ │ └── DashboardStatsUI.kt │ │ │ ├── goals │ │ │ ├── active │ │ │ │ ├── ActiveGoalScreen.kt │ │ │ │ └── ActiveGoalsUI.kt │ │ │ ├── addEdit │ │ │ │ ├── AddEditGoalScreen.kt │ │ │ │ └── AddEditGoalUI.kt │ │ │ ├── components │ │ │ │ ├── AppsListCard.kt │ │ │ │ ├── DetailsCard.kt │ │ │ │ ├── EmptyGoalsIndicator.kt │ │ │ │ ├── NewGoalSheet.kt │ │ │ │ └── UpdateValueDialog.kt │ │ │ ├── details │ │ │ │ ├── GoalDetailsScreen.kt │ │ │ │ └── GoalDetailsUI.kt │ │ │ └── inactive │ │ │ │ ├── InactiveGoalScreen.kt │ │ │ │ └── InactiveGoalsUI.kt │ │ │ ├── onboarding │ │ │ ├── OnBoardingScreen.kt │ │ │ ├── OnBoardingUI.kt │ │ │ ├── components │ │ │ │ ├── OnBoardingBottomBar.kt │ │ │ │ └── PermissionStatusCard.kt │ │ │ └── pages │ │ │ │ ├── AlarmsAndRemindersPage.kt │ │ │ │ ├── AllSetPage.kt │ │ │ │ ├── NotificationsPage.kt │ │ │ │ ├── OverlayPage.kt │ │ │ │ ├── PermissionsPage.kt │ │ │ │ ├── ThemesPage.kt │ │ │ │ ├── UsageAccessPage.kt │ │ │ │ └── WelcomePage.kt │ │ │ ├── screentime │ │ │ ├── appStatsDetails │ │ │ │ ├── AppScreenTimeStatsScreen.kt │ │ │ │ └── AppScreenTimeStatsUI.kt │ │ │ ├── components │ │ │ │ ├── AppNameEntry.kt │ │ │ │ ├── AppTimeLimitDialog.kt │ │ │ │ ├── AppTimeLimitUI.kt │ │ │ │ ├── FocusMode.kt │ │ │ │ ├── GetScreenTimeBarChartData.kt │ │ │ │ ├── ManageAppsUI.kt │ │ │ │ ├── ScreenTimeWeekSelectorButton.kt │ │ │ │ └── UsagePermissionDialog.kt │ │ │ ├── limits │ │ │ │ ├── ScreenTimeLimitsScreen.kt │ │ │ │ └── ScreenTimeLimitsUI.kt │ │ │ └── statistics │ │ │ │ ├── ScreenTimeStatisticsScreen.kt │ │ │ │ └── ScreenTimeStatisticsUI.kt │ │ │ ├── settings │ │ │ ├── SettingsScreen.kt │ │ │ ├── SettingsUI.kt │ │ │ ├── account │ │ │ │ ├── ManageAccountScreen.kt │ │ │ │ ├── ManageAccountUI.kt │ │ │ │ └── UserAccountUI.kt │ │ │ └── components │ │ │ │ ├── AppAboutInfo.kt │ │ │ │ ├── CoffeeProductsSheet.kt │ │ │ │ ├── ThemeSelectCard.kt │ │ │ │ └── ThemesDialog.kt │ │ │ ├── tasks │ │ │ ├── addEdit │ │ │ │ ├── AddEditTaskScreen.kt │ │ │ │ └── AddEditTaskUI.kt │ │ │ ├── components │ │ │ │ ├── FullEmptyTasksIndicator.kt │ │ │ │ ├── GetWeeklyTasksBarChartData.kt │ │ │ │ ├── ManageTaskLabelsSheet.kt │ │ │ │ └── ModifyTaskLabel.kt │ │ │ ├── details │ │ │ │ ├── TaskDetailsScreen.kt │ │ │ │ └── TaskDetailsUI.kt │ │ │ ├── done │ │ │ │ ├── CompletedTasksScreen.kt │ │ │ │ └── CompletedTasksUI.kt │ │ │ ├── pending │ │ │ │ ├── PendingTasksScreen.kt │ │ │ │ └── PendingTasksUI.kt │ │ │ ├── search │ │ │ │ ├── TasksSearchScreen.kt │ │ │ │ └── TasksSearchUI.kt │ │ │ └── statistics │ │ │ │ ├── TasksStatisticsScreen.kt │ │ │ │ └── TasksStatisticsUI.kt │ │ │ └── util │ │ │ ├── BackPressHandler.kt │ │ │ ├── BottomBarVisibilityHandler.kt │ │ │ ├── FetchMoreDataHandler.kt │ │ │ ├── PermissionCheckHandler.kt │ │ │ ├── Permissions.kt │ │ │ └── SnackbarModifier.kt │ │ └── res │ │ ├── drawable │ │ └── no_tasks.xml │ │ └── raw │ │ ├── no_data.json │ │ ├── no_permission.json │ │ ├── no_task_animation.json │ │ ├── search_animation.json │ │ └── task_saved.json └── widgets │ ├── .gitignore │ ├── build.gradle.kts │ ├── consumer-rules.pro │ ├── proguard-rules.pro │ └── src │ ├── androidTest │ └── java │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── widgets │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── widgets │ │ │ ├── components │ │ │ ├── common │ │ │ │ ├── RoundCheckBox.kt │ │ │ │ ├── WidgetIconButton.kt │ │ │ │ └── WidgetTopBar.kt │ │ │ └── tasks │ │ │ │ ├── TaskEntry.kt │ │ │ │ └── TaskEntryLabels.kt │ │ │ ├── core │ │ │ ├── PendingIntent.kt │ │ │ ├── ReluctGlanceWidget.kt │ │ │ ├── ReluctGlanceWidgetReceiver.kt │ │ │ └── Theme.kt │ │ │ └── tasks │ │ │ ├── HelloWidget.kt │ │ │ ├── HelloWidgetReceiver.kt │ │ │ ├── PendingTasksList.kt │ │ │ ├── PendingTasksWidget.kt │ │ │ ├── PendingTasksWidgetReceiver.kt │ │ │ ├── actions │ │ │ ├── PendingTasksSource.kt │ │ │ └── PendingTasksWidgetActions.kt │ │ │ └── state │ │ │ ├── PendingTasksInfo.kt │ │ │ └── PendingTasksStateDefinition.kt │ └── res │ │ ├── drawable │ │ ├── ic_round_refresh_24.xml │ │ └── pending_tasks_preview.png │ │ ├── values-night-v31 │ │ └── glance_colors.xml │ │ ├── values-night │ │ └── glance_colors.xml │ │ ├── values-v31 │ │ └── glance_colors.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── glance_colors.xml │ │ └── strings.xml │ │ └── xml │ │ ├── pending_tasks_widget_info.xml │ │ └── widget_hello_info.xml │ └── test │ └── java │ └── work │ └── racka │ └── reluct │ └── widgets │ └── ExampleUnitTest.kt ├── build-configs ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ ├── extensions │ └── VersionCatalogExtensions.kt │ └── quality │ ├── DetektSetup.kt │ ├── SetDetekt.kt │ └── detekt.gradle.kts ├── build.gradle.kts ├── common ├── app-usage-stats │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── app │ │ │ │ └── usage │ │ │ │ └── stats │ │ │ │ ├── di │ │ │ │ └── Platform.kt │ │ │ │ ├── manager │ │ │ │ └── AndroidUsageDataManager.kt │ │ │ │ └── util │ │ │ │ └── Helpers.kt │ │ └── res │ │ │ └── drawable │ │ │ └── default_app_icon.webp │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── app │ │ │ └── usage │ │ │ └── stats │ │ │ ├── di │ │ │ ├── AppUsageStats.kt │ │ │ └── Platform.kt │ │ │ ├── manager │ │ │ └── UsageDataManager.kt │ │ │ ├── model │ │ │ ├── DataAppUsageInfo.kt │ │ │ └── DataUsageStats.kt │ │ │ └── util │ │ │ └── Util.kt │ │ ├── commonTest │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── app │ │ │ └── usage │ │ │ └── stats │ │ │ └── util │ │ │ └── TestData.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── app │ │ └── usage │ │ └── stats │ │ ├── di │ │ └── Platform.kt │ │ └── manager │ │ └── DesktopUsageDataManager.kt ├── authentication │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── authentication │ │ │ ├── di │ │ │ └── Platform.kt │ │ │ ├── managers │ │ │ ├── AndroidFirebaseManageUser.kt │ │ │ └── AndroidFirebaseUserAuthentication.kt │ │ │ └── mappers │ │ │ └── AuthUser.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── authentication │ │ │ ├── di │ │ │ ├── Authentication.kt │ │ │ └── Platform.kt │ │ │ ├── extras │ │ │ └── Messages.kt │ │ │ ├── managers │ │ │ ├── ManageUser.kt │ │ │ └── UserAuthentication.kt │ │ │ └── models │ │ │ ├── AuthLoginUser.kt │ │ │ ├── AuthRegisterUser.kt │ │ │ └── AuthUser.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── authentication │ │ ├── di │ │ └── Platform.kt │ │ └── managers │ │ ├── DesktopManageUser.kt │ │ └── DesktopUserAuthentication.kt ├── billing │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── billing │ │ │ ├── api │ │ │ └── RevenueCatAndroid.kt │ │ │ ├── di │ │ │ └── Platform.kt │ │ │ ├── products │ │ │ └── ProductInfo.kt │ │ │ └── revenuecat │ │ │ ├── PackageMapper.kt │ │ │ ├── ProductSkuHelper.kt │ │ │ └── PurchaseAction.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── billing │ │ │ ├── api │ │ │ └── BillingApi.kt │ │ │ ├── di │ │ │ ├── Billing.kt │ │ │ └── Platform.kt │ │ │ └── products │ │ │ ├── Product.kt │ │ │ ├── ProductInfo.kt │ │ │ ├── ProductOffered.kt │ │ │ ├── Products.kt │ │ │ └── Sku.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── billing │ │ ├── api │ │ └── DesktopBilling.kt │ │ ├── di │ │ └── Platform.kt │ │ └── products │ │ └── ProductInfo.kt ├── core-navigation │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── core │ │ │ └── navigation │ │ │ ├── composeDestinations │ │ │ ├── OtherDestination.kt │ │ │ ├── dashboard │ │ │ │ ├── DashboardOverviewDestination.kt │ │ │ │ └── DashboardStatsDestination.kt │ │ │ ├── goals │ │ │ │ ├── ActiveGoalsDestination.kt │ │ │ │ ├── AddEditGoalDestination.kt │ │ │ │ ├── GoalDetailsDestination.kt │ │ │ │ └── InactiveGoalsDestination.kt │ │ │ ├── onboarding │ │ │ │ ├── AuthenticationDestination.kt │ │ │ │ └── OnBoardingDestination.kt │ │ │ ├── screentime │ │ │ │ ├── AppScreenTimeStatsDestination.kt │ │ │ │ ├── ScreenTimeLimitsDestination.kt │ │ │ │ └── ScreenTimeStatsDestination.kt │ │ │ ├── settings │ │ │ │ ├── ManageAccountDestination.kt │ │ │ │ └── SettingsDestination.kt │ │ │ └── tasks │ │ │ │ ├── AddEditTaskDestination.kt │ │ │ │ ├── CompletedTasksDestination.kt │ │ │ │ ├── PendingTasksDestination.kt │ │ │ │ ├── SearchTasksDestination.kt │ │ │ │ ├── TaskDetailsDestination.kt │ │ │ │ └── TasksStatisticsDestination.kt │ │ │ └── destination │ │ │ ├── NavDefaults.kt │ │ │ └── NavDestination.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── core │ │ │ └── navigation │ │ │ └── checks │ │ │ └── InitialNavCheck.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── core │ │ └── navigation │ │ └── destination │ │ ├── AppNavConfig.kt │ │ └── graphs │ │ ├── GoalsConfig.kt │ │ ├── ScreenTimeConfig.kt │ │ └── TasksConfig.kt ├── di-integration │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ └── AndroidManifest.xml │ │ └── commonMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── di │ │ └── intergration │ │ └── KoinMain.kt ├── domain │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── domain │ │ │ │ ├── alarms │ │ │ │ ├── AlarmReminderNotifications.kt │ │ │ │ ├── AlarmsKeys.kt │ │ │ │ ├── AlarmsReceiver.kt │ │ │ │ └── RestartAlarmsReceiver.kt │ │ │ │ ├── di │ │ │ │ ├── CoroutineDispatchers.kt │ │ │ │ └── Platform.kt │ │ │ │ ├── usecases │ │ │ │ ├── appInfo │ │ │ │ │ ├── AndroidGetAppInfo.kt │ │ │ │ │ └── AndroidGetInstalledApps.kt │ │ │ │ └── tasks │ │ │ │ │ └── AndroidManageTasksAlarms.kt │ │ │ │ └── util │ │ │ │ └── Helpers.kt │ │ └── res │ │ │ ├── drawable │ │ │ └── ic_baseline_fact_check_24.xml │ │ │ └── values │ │ │ └── strings.xml │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── domain │ │ │ ├── di │ │ │ ├── CoroutineDispatchers.kt │ │ │ ├── Domain.kt │ │ │ └── Platform.kt │ │ │ ├── mappers │ │ │ ├── authentication │ │ │ │ └── UserData.kt │ │ │ ├── goals │ │ │ │ └── Goal.kt │ │ │ ├── limits │ │ │ │ ├── Limits.kt │ │ │ │ └── TimeLimit.kt │ │ │ ├── tasks │ │ │ │ ├── EditTask.kt │ │ │ │ ├── Task.kt │ │ │ │ └── TaskLabel.kt │ │ │ └── usagestats │ │ │ │ ├── AppUsageInfo.kt │ │ │ │ ├── AppUsageStats.kt │ │ │ │ └── UsageStats.kt │ │ │ ├── pagination │ │ │ ├── DefaultPaginator.kt │ │ │ └── Paginator.kt │ │ │ └── usecases │ │ │ ├── appInfo │ │ │ ├── GetAppInfo.kt │ │ │ └── GetInstalledApps.kt │ │ │ ├── appUsage │ │ │ ├── GetAppUsageInfo.kt │ │ │ ├── GetUsageStats.kt │ │ │ └── impl │ │ │ │ ├── GetAppUsageInfoImpl.kt │ │ │ │ └── GetUsageStatsImpl.kt │ │ │ ├── authentication │ │ │ ├── AuthVerifications.kt │ │ │ ├── LoginSignupUser.kt │ │ │ ├── UserAccountManagement.kt │ │ │ └── impl │ │ │ │ ├── LoginSignupUserImpl.kt │ │ │ │ └── UserAccountManagementImpl.kt │ │ │ ├── billing │ │ │ ├── ManageCoffeeProducts.kt │ │ │ └── impl │ │ │ │ └── ManageCoffeeProductsImpl.kt │ │ │ ├── goals │ │ │ ├── GetGoals.kt │ │ │ ├── ModifyGoals.kt │ │ │ └── impl │ │ │ │ ├── GetGoalsImpl.kt │ │ │ │ └── ModifyGoalsImpl.kt │ │ │ ├── limits │ │ │ ├── GetAppLimits.kt │ │ │ ├── GetDistractingApps.kt │ │ │ ├── GetPausedApps.kt │ │ │ ├── ManageAppTimeLimit.kt │ │ │ ├── ManageDistractingApps.kt │ │ │ ├── ManageFocusMode.kt │ │ │ ├── ManagePausedApps.kt │ │ │ ├── ModifyAppLimits.kt │ │ │ └── impl │ │ │ │ ├── GetAppLimitsImpl.kt │ │ │ │ ├── GetDistractingAppsImpl.kt │ │ │ │ ├── GetPausedAppsImpl.kt │ │ │ │ ├── ManageAppTimeLimitImpl.kt │ │ │ │ ├── ManageDistractingAppsImpl.kt │ │ │ │ ├── ManageFocusModeImpl.kt │ │ │ │ ├── ManagePausedAppsImpl.kt │ │ │ │ └── ModifyAppLimitsImpl.kt │ │ │ ├── tasks │ │ │ ├── GetGroupedTasksStats.kt │ │ │ ├── GetTasksUseCase.kt │ │ │ ├── ManageTaskLabels.kt │ │ │ ├── ManageTasksAlarms.kt │ │ │ ├── ModifyTaskUseCase.kt │ │ │ └── impl │ │ │ │ ├── GetGroupedTasksStatsImpl.kt │ │ │ │ ├── GetTasksUseCaseImpl.kt │ │ │ │ ├── ManageTaskLabelsImpl.kt │ │ │ │ └── ModifyTaskUseCaseImpl.kt │ │ │ └── time │ │ │ ├── GetWeekRangeFromOffset.kt │ │ │ └── impl │ │ │ └── GetWeekRangeFromOffsetImpl.kt │ │ ├── commonTest │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── domain │ │ │ ├── usecases │ │ │ ├── AuthVerificationsTest.kt │ │ │ ├── GetTasksUseCaseTest.kt │ │ │ └── ModifyTaskUseCaseTest.kt │ │ │ └── util │ │ │ └── TestData.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── domain │ │ ├── di │ │ ├── CoroutineDispatchers.kt │ │ └── Platform.kt │ │ └── usecases │ │ ├── appInfo │ │ ├── DesktopGetAppInfo.kt │ │ └── DesktopGetInstalledApps.kt │ │ └── tasks │ │ └── DesktopManageTasksAlarms.kt ├── features │ ├── dashboard │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidMain │ │ │ └── AndroidManifest.xml │ │ │ └── commonMain │ │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── features │ │ │ └── dashboard │ │ │ ├── di │ │ │ └── Dashboard.kt │ │ │ ├── overview │ │ │ ├── DashboardOverviewViewModel.kt │ │ │ └── states │ │ │ │ ├── DashboardEvents.kt │ │ │ │ └── DashboardOverviewState.kt │ │ │ └── statistics │ │ │ └── DashboardStatisticsViewModel.kt │ ├── goals │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidMain │ │ │ └── AndroidManifest.xml │ │ │ └── commonMain │ │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── features │ │ │ └── goals │ │ │ ├── active │ │ │ ├── ActiveGoalsViewModel.kt │ │ │ └── states │ │ │ │ ├── ActiveGoalsState.kt │ │ │ │ ├── DefaultGoals.kt │ │ │ │ ├── GoalsEvents.kt │ │ │ │ └── GoalsListState.kt │ │ │ ├── addEditGoal │ │ │ ├── AddEditGoalViewModel.kt │ │ │ └── states │ │ │ │ └── AddEditGoalState.kt │ │ │ ├── details │ │ │ ├── GoalDetailsViewModel.kt │ │ │ └── states │ │ │ │ └── GoalDetailsState.kt │ │ │ ├── di │ │ │ └── GoalsDI.kt │ │ │ └── inactive │ │ │ └── InActiveGoalsViewModel.kt │ ├── onboarding │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidMain │ │ │ └── AndroidManifest.xml │ │ │ └── commonMain │ │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── features │ │ │ └── onboarding │ │ │ ├── di │ │ │ └── OnBoarding.kt │ │ │ ├── states │ │ │ ├── auth │ │ │ │ ├── LoginSignupEvent.kt │ │ │ │ └── LoginSignupState.kt │ │ │ └── onBoarding │ │ │ │ ├── OnBoardingState.kt │ │ │ │ └── PermissionType.kt │ │ │ └── vm │ │ │ ├── LoginSignupViewModel.kt │ │ │ └── OnBoardingViewModel.kt │ ├── screen-time │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidMain │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── work │ │ │ │ │ └── racka │ │ │ │ │ └── reluct │ │ │ │ │ └── common │ │ │ │ │ └── features │ │ │ │ │ └── screenTime │ │ │ │ │ ├── di │ │ │ │ │ └── Platform.kt │ │ │ │ │ ├── permissions │ │ │ │ │ └── UsageAccessPermission.kt │ │ │ │ │ ├── services │ │ │ │ │ ├── AndroidScreenTimeServices.kt │ │ │ │ │ ├── RestartScreenTimeServiceReceiver.kt │ │ │ │ │ ├── ScreenTimeDataProviders.kt │ │ │ │ │ ├── ScreenTimeLimitService.kt │ │ │ │ │ └── ScreenTimeServiceNotification.kt │ │ │ │ │ ├── ui │ │ │ │ │ ├── components │ │ │ │ │ │ └── AppNameEntry.kt │ │ │ │ │ └── overlay │ │ │ │ │ │ ├── AppLimitedOverlayUI.kt │ │ │ │ │ │ ├── AppLimitedOverlayView.kt │ │ │ │ │ │ ├── LimitsOverlayParams.kt │ │ │ │ │ │ └── OverlayLifecycleOwner.kt │ │ │ │ │ └── work │ │ │ │ │ └── ResumeAppsWork.kt │ │ │ └── res │ │ │ │ ├── drawable │ │ │ │ ├── ic_twotone_aod_24.xml │ │ │ │ └── ic_twotone_report_24.xml │ │ │ │ └── values │ │ │ │ └── strings.xml │ │ │ ├── commonMain │ │ │ └── kotlin │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── features │ │ │ │ └── screenTime │ │ │ │ ├── di │ │ │ │ ├── Platform.kt │ │ │ │ └── ScreenTime.kt │ │ │ │ ├── limits │ │ │ │ ├── ScreenTimeLimitsViewModel.kt │ │ │ │ └── states │ │ │ │ │ ├── AppTimeLimitState.kt │ │ │ │ │ ├── ScreenTimeLimitState.kt │ │ │ │ │ └── ScreenTimeLimitsEvents.kt │ │ │ │ ├── services │ │ │ │ └── ScreenTimeServices.kt │ │ │ │ ├── statistics │ │ │ │ ├── AppScreenTimeStatsViewModel.kt │ │ │ │ ├── ScreenTimeStatsViewModel.kt │ │ │ │ └── states │ │ │ │ │ ├── ScreenTimeStatsEvents.kt │ │ │ │ │ ├── ScreenTimeStatsSelectedInfo.kt │ │ │ │ │ ├── allStats │ │ │ │ │ └── ScreenTimeStatsState.kt │ │ │ │ │ └── appStats │ │ │ │ │ └── AppScreenTimeStatsState.kt │ │ │ │ └── util │ │ │ │ └── Constants.kt │ │ │ └── desktopMain │ │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── features │ │ │ └── screenTime │ │ │ ├── di │ │ │ └── Platform.kt │ │ │ └── services │ │ │ └── DesktopScreenTimeServices.kt │ ├── settings │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidMain │ │ │ └── AndroidManifest.xml │ │ │ └── commonMain │ │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── features │ │ │ └── settings │ │ │ ├── AppSettingsViewModel.kt │ │ │ ├── UserAccountViewModel.kt │ │ │ ├── di │ │ │ └── AppSettings.kt │ │ │ └── states │ │ │ ├── SettingsEvents.kt │ │ │ ├── SettingsState.kt │ │ │ ├── UserAccountEvents.kt │ │ │ └── UserAccountState.kt │ └── tasks │ │ ├── build.gradle.kts │ │ └── src │ │ ├── androidMain │ │ └── AndroidManifest.xml │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── features │ │ │ └── tasks │ │ │ ├── addEditTask │ │ │ ├── AddEditTaskViewModel.kt │ │ │ └── DefaultTasks.kt │ │ │ ├── completedTasks │ │ │ └── CompletedTasksViewModel.kt │ │ │ ├── di │ │ │ └── Tasks.kt │ │ │ ├── pendingTasks │ │ │ └── PendingTasksViewModel.kt │ │ │ ├── searchTasks │ │ │ └── SearchTasksViewModel.kt │ │ │ ├── states │ │ │ └── TaskDetailsState.kt │ │ │ ├── statistics │ │ │ └── TasksStatisticsViewModel.kt │ │ │ ├── taskDetails │ │ │ └── TaskDetailsViewModel.kt │ │ │ └── util │ │ │ └── Constants.kt │ │ └── commonTest │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── features.tasks │ │ ├── addEditTask │ │ └── AddEditTaskTest.kt │ │ ├── completedTasks │ │ └── CompletedTasksTest.kt │ │ ├── pendingTasks │ │ └── PendingTasksTest.kt │ │ ├── statistics │ │ └── TasksStatisticsTest.kt │ │ ├── taskDetails │ │ └── TaskDetailsTest.kt │ │ └── util │ │ └── TestData.kt ├── model │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── model │ │ │ ├── domain │ │ │ └── core │ │ │ │ └── Icon.kt │ │ │ └── util │ │ │ └── UUIDGen.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── model │ │ │ ├── domain │ │ │ ├── about │ │ │ │ └── AppAbout.kt │ │ │ ├── appInfo │ │ │ │ └── AppInfo.kt │ │ │ ├── authentication │ │ │ │ ├── AuthResults.kt │ │ │ │ ├── EmailUserLogin.kt │ │ │ │ ├── RegisterUser.kt │ │ │ │ └── User.kt │ │ │ ├── core │ │ │ │ └── Icon.kt │ │ │ ├── goals │ │ │ │ ├── Goal.kt │ │ │ │ ├── GoalDuration.kt │ │ │ │ ├── GoalInterval.kt │ │ │ │ └── GoalType.kt │ │ │ ├── limits │ │ │ │ ├── AppLimits.kt │ │ │ │ └── AppTimeLimit.kt │ │ │ ├── tasks │ │ │ │ ├── DailyTasksStats.kt │ │ │ │ ├── EditTask.kt │ │ │ │ ├── Task.kt │ │ │ │ └── TaskLabel.kt │ │ │ └── usagestats │ │ │ │ ├── AppUsageInfo.kt │ │ │ │ ├── AppUsageStats.kt │ │ │ │ └── UsageStats.kt │ │ │ ├── enums │ │ │ └── billing │ │ │ │ ├── ProductsOffered.kt │ │ │ │ └── Sku.kt │ │ │ ├── states │ │ │ ├── about │ │ │ │ ├── AboutSideEffect.kt │ │ │ │ └── AboutState.kt │ │ │ └── tasks │ │ │ │ ├── AddEditTasksState.kt │ │ │ │ ├── CompletedTasksState.kt │ │ │ │ ├── PendingTasksState.kt │ │ │ │ ├── SearchTasksState.kt │ │ │ │ ├── TasksEvents.kt │ │ │ │ └── TasksStatisticsState.kt │ │ │ └── util │ │ │ ├── DataMappers.kt │ │ │ ├── Resource.kt │ │ │ ├── UUIDGen.kt │ │ │ ├── list │ │ │ └── PersistentListHelpers.kt │ │ │ └── time │ │ │ ├── StatisticsTimeUtils.kt │ │ │ ├── TimePeriod.kt │ │ │ ├── TimeUtils.kt │ │ │ └── Week.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── model │ │ ├── domain │ │ └── core │ │ │ └── Icon.kt │ │ └── util │ │ └── UUIDGen.kt ├── mvvm-core │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── common │ │ │ └── mvvm │ │ │ ├── koin │ │ │ ├── compose │ │ │ │ └── GetViewModel.kt │ │ │ └── vm │ │ │ │ ├── ActivityViewModel.kt │ │ │ │ ├── FragmentViewModel.kt │ │ │ │ └── KoinCommonViewModel.kt │ │ │ └── viewmodel │ │ │ └── CommonViewModel.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── common │ │ │ └── mvvm │ │ │ ├── koin │ │ │ ├── decompose │ │ │ │ └── DecomposeVMLazy.kt │ │ │ └── vm │ │ │ │ └── KoinCommonViewModel.kt │ │ │ └── viewmodel │ │ │ └── CommonViewModel.kt │ │ ├── desktopMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── common │ │ │ └── mvvm │ │ │ ├── koin │ │ │ ├── compose │ │ │ │ ├── Get.kt │ │ │ │ └── GetViewModel.kt │ │ │ ├── decompose │ │ │ │ └── ViewModelExt.kt │ │ │ └── vm │ │ │ │ └── KoinCommonViewModel.kt │ │ │ └── viewmodel │ │ │ └── CommonViewModel.kt │ │ └── jsMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── common │ │ └── mvvm │ │ ├── koin │ │ └── vm │ │ │ └── KoinCommonViewModel.kt │ │ └── viewmodel │ │ └── CommonViewModel.kt ├── network │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── network │ │ │ ├── di │ │ │ └── Platform.kt │ │ │ └── sync │ │ │ ├── FirebaseNetworkSyncService.kt │ │ │ └── tasks │ │ │ └── FirebaseTasksUpload.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── network │ │ │ ├── di │ │ │ ├── Network.kt │ │ │ └── Platform.kt │ │ │ ├── sync │ │ │ ├── DbNetworkSync.kt │ │ │ └── tasks │ │ │ │ └── TasksUpload.kt │ │ │ └── util │ │ │ └── Constants.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── network │ │ ├── di │ │ └── Platform.kt │ │ └── sync │ │ ├── DesktopNetworkSync.kt │ │ └── tasks │ │ └── DesktopTasksUpload.kt ├── persistence │ ├── database │ │ ├── build.gradle.kts │ │ └── src │ │ │ ├── androidAndroidTest │ │ │ └── kotlin │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── database │ │ │ │ └── di │ │ │ │ └── getDatabaseWrapper.kt │ │ │ ├── androidMain │ │ │ ├── AndroidManifest.xml │ │ │ └── kotlin │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── database │ │ │ │ └── di │ │ │ │ ├── CoroutineDispatchers.kt │ │ │ │ └── Platform.kt │ │ │ ├── androidTest │ │ │ └── kotlin │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── database │ │ │ │ └── di │ │ │ │ └── GetDatabaseWrapper.kt │ │ │ ├── commonMain │ │ │ ├── kotlin │ │ │ │ └── work │ │ │ │ │ └── racka │ │ │ │ │ └── reluct │ │ │ │ │ └── common │ │ │ │ │ └── database │ │ │ │ │ ├── adapters │ │ │ │ │ ├── ColumnAdapters.kt │ │ │ │ │ ├── GoalsTableAdapter.kt │ │ │ │ │ └── TasksTableAdapter.kt │ │ │ │ │ ├── dao │ │ │ │ │ ├── DatabaseWrapper.kt │ │ │ │ │ ├── goals │ │ │ │ │ │ ├── GoalsDao.kt │ │ │ │ │ │ ├── GoalsDaoImpl.kt │ │ │ │ │ │ └── GoalsHelpers.kt │ │ │ │ │ ├── screentime │ │ │ │ │ │ ├── LimitsDao.kt │ │ │ │ │ │ ├── LimitsDaoImpl.kt │ │ │ │ │ │ └── LimitsHelpers.kt │ │ │ │ │ └── tasks │ │ │ │ │ │ ├── TasksDao.kt │ │ │ │ │ │ ├── TasksDaoImpl.kt │ │ │ │ │ │ └── TasksHelpers.kt │ │ │ │ │ ├── di │ │ │ │ │ ├── CoroutineDispatchers.kt │ │ │ │ │ ├── Database.kt │ │ │ │ │ └── Platform.kt │ │ │ │ │ ├── models │ │ │ │ │ ├── GoalDbObject.kt │ │ │ │ │ ├── LimitsDbObject.kt │ │ │ │ │ ├── TaskDbObject.kt │ │ │ │ │ └── TaskLabelDbObject.kt │ │ │ │ │ └── util │ │ │ │ │ ├── Constants.kt │ │ │ │ │ └── Helpers.kt │ │ │ └── sqldelight │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── database │ │ │ │ ├── files │ │ │ │ ├── 1.db │ │ │ │ └── 2.db │ │ │ │ ├── migrations │ │ │ │ ├── 0.sqm │ │ │ │ └── 1.sqm │ │ │ │ └── tables │ │ │ │ ├── GoalsTable.sq │ │ │ │ ├── LimitsTable.sq │ │ │ │ ├── TaskLabelsTable.sq │ │ │ │ └── TasksTable.sq │ │ │ ├── commonTest │ │ │ └── kotlin │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── database │ │ │ │ ├── dao │ │ │ │ ├── goals │ │ │ │ │ ├── FakeGoalsDao.kt │ │ │ │ │ └── GoalsDaoImplTest.kt │ │ │ │ └── tasks │ │ │ │ │ ├── FakeTasksDao.kt │ │ │ │ │ └── TasksDaoImplTest.kt │ │ │ │ ├── di │ │ │ │ └── GetDatabaseWrapper.kt │ │ │ │ └── util │ │ │ │ ├── GoalsTestData.kt │ │ │ │ └── TasksTestData.kt │ │ │ ├── desktopMain │ │ │ └── kotlin │ │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── common │ │ │ │ └── database │ │ │ │ └── di │ │ │ │ ├── CoroutineDispatchers.kt │ │ │ │ └── Platform.kt │ │ │ └── desktopTest │ │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── database │ │ │ └── di │ │ │ └── GetDatabaseWrapper.kt │ └── settings │ │ ├── build.gradle.kts │ │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── settings │ │ │ ├── di │ │ │ └── Platform.kt │ │ │ └── util │ │ │ └── Playground.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── settings │ │ │ ├── AutoFocusMode.kt │ │ │ ├── Keys.kt │ │ │ ├── MultiplatformSettings.kt │ │ │ ├── MultiplatformSettingsImpl.kt │ │ │ └── di │ │ │ ├── MultiplatformSettings.kt │ │ │ └── Platform.kt │ │ ├── commonTest │ │ └── kotlin │ │ │ └── work.racka.reluct.common.settings │ │ │ ├── FakeMultiplatformSettings.kt │ │ │ └── MultiplatformSettingsImplTest.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── settings │ │ └── di │ │ └── Platform.kt └── system-services │ ├── build.gradle.kts │ └── src │ ├── androidMain │ ├── AndroidManifest.xml │ ├── kotlin │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── common │ │ │ └── services │ │ │ ├── di │ │ │ └── PlatformSystemServicesModule.kt │ │ │ ├── haptics │ │ │ └── AndroidHapticFeedback.kt │ │ │ ├── notifications │ │ │ ├── NotificationChannelInfo.kt │ │ │ ├── SimpleAndroidNotification.kt │ │ │ └── defaultChannels │ │ │ │ └── AppAlerts.kt │ │ │ └── util │ │ │ └── IntentData.kt │ └── res │ │ └── values │ │ └── strings.xml │ ├── commonMain │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── common │ │ └── services │ │ ├── di │ │ └── SystemServices.kt │ │ ├── haptics │ │ └── HapticFeedback.kt │ │ └── notifications │ │ └── NotificationData.kt │ └── desktopMain │ └── kotlin │ └── work │ └── racka │ └── reluct │ └── common │ └── services │ ├── di │ └── PlatformSystemServicesModule.kt │ └── haptics │ └── DesktopHapticFeedback.kt ├── compose-common ├── charts │ ├── README.md │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── compose │ │ │ └── common │ │ │ └── charts │ │ │ ├── common │ │ │ └── ColorUtils.kt │ │ │ └── util │ │ │ ├── DrawText.kt │ │ │ └── TextBounds.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── compose │ │ │ └── common │ │ │ └── charts │ │ │ ├── barChart │ │ │ ├── BarChart.kt │ │ │ ├── BarChartData.kt │ │ │ ├── BarChartOptions.kt │ │ │ ├── BarChartUtils.kt │ │ │ └── renderer │ │ │ │ ├── bar │ │ │ │ ├── BarDrawer.kt │ │ │ │ └── SimpleBarDrawer.kt │ │ │ │ ├── label │ │ │ │ ├── LabelDrawer.kt │ │ │ │ └── SimpleValueDrawer.kt │ │ │ │ ├── xaxis │ │ │ │ ├── SimpleXAxisDrawer.kt │ │ │ │ └── XAxisDrawer.kt │ │ │ │ └── yaxis │ │ │ │ ├── SimpleYAxisDrawer.kt │ │ │ │ └── YAxisDrawer.kt │ │ │ ├── common │ │ │ ├── AxisLine.kt │ │ │ ├── ColorUtils.kt │ │ │ └── SimpleChartAnimation.kt │ │ │ ├── pieChart │ │ │ ├── PieChart.kt │ │ │ ├── PieChartData.kt │ │ │ ├── PieChartUtils.kt │ │ │ └── renderer │ │ │ │ ├── slice │ │ │ │ ├── SimpleSliceDrawer.kt │ │ │ │ └── SliceDrawer.kt │ │ │ │ └── text │ │ │ │ ├── SimpleTextDrawer.kt │ │ │ │ └── TextDrawer.kt │ │ │ └── util │ │ │ ├── DrawText.kt │ │ │ └── TextBounds.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── compose │ │ └── common │ │ └── charts │ │ ├── common │ │ └── ColorUtils.kt │ │ └── util │ │ ├── DrawText.kt │ │ └── TextBounds.kt ├── components │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── compose │ │ │ └── common │ │ │ └── components │ │ │ ├── dialogs │ │ │ └── MultiplatformDialog.kt │ │ │ ├── images │ │ │ ├── AsyncImage.kt │ │ │ └── LottieAnimationWithDescription.kt │ │ │ ├── resources │ │ │ ├── AssetResourceExt.kt │ │ │ └── ComposeExt.kt │ │ │ ├── statsHelpers │ │ │ └── StatsDispatcher.kt │ │ │ └── util │ │ │ ├── Color.kt │ │ │ ├── ColorPalette.kt │ │ │ └── PlatformPaddings.kt │ │ ├── commonMain │ │ ├── kotlin │ │ │ └── work │ │ │ │ └── racka │ │ │ │ └── reluct │ │ │ │ └── compose │ │ │ │ └── common │ │ │ │ └── components │ │ │ │ ├── animations │ │ │ │ └── SlideAnimations.kt │ │ │ │ ├── bottomSheet │ │ │ │ ├── SheetComponents.kt │ │ │ │ ├── addEditGoal │ │ │ │ │ ├── AddEditGoalComponents.kt │ │ │ │ │ └── LazyColumnAddEditGoal.kt │ │ │ │ ├── addEditTask │ │ │ │ │ ├── DateTimePills.kt │ │ │ │ │ └── LazyColumnAddEditTaskFields.kt │ │ │ │ └── taskLabels │ │ │ │ │ ├── AddEditTaskLabelSheet.kt │ │ │ │ │ ├── LazyColumnSelectTaskLabelsSheet.kt │ │ │ │ │ └── TaskLabelsList.kt │ │ │ │ ├── buttons │ │ │ │ ├── CollapsingFloatingButton.kt │ │ │ │ ├── OutlinedReluctButton.kt │ │ │ │ ├── ReluctButton.kt │ │ │ │ ├── ReluctFloatingActionButton.kt │ │ │ │ ├── ScrollToTop.kt │ │ │ │ └── ValueOffsetButton.kt │ │ │ │ ├── cards │ │ │ │ ├── appUsageEntry │ │ │ │ │ ├── AppUsageEntry.kt │ │ │ │ │ └── AppUsageEntryLabels.kt │ │ │ │ ├── cardWithActions │ │ │ │ │ ├── ReluctDescriptionCard.kt │ │ │ │ │ └── ReluctSwitchCard.kt │ │ │ │ ├── date │ │ │ │ │ └── SelectedDaysOfWeekViewer.kt │ │ │ │ ├── goalEntry │ │ │ │ │ ├── GoalEntry.kt │ │ │ │ │ ├── GoalEntryLabels.kt │ │ │ │ │ └── GoalHeadingSwitchCard.kt │ │ │ │ ├── headers │ │ │ │ │ └── ListGroupHeadingHeader.kt │ │ │ │ ├── permissions │ │ │ │ │ └── PermissionsCard.kt │ │ │ │ ├── settings │ │ │ │ │ └── EntryWithCheckbox.kt │ │ │ │ ├── statistics │ │ │ │ │ ├── BarChartDefaults.kt │ │ │ │ │ ├── ChartData.kt │ │ │ │ │ ├── StatisticsBarChartBase.kt │ │ │ │ │ ├── StatisticsBarChartCard.kt │ │ │ │ │ ├── piechart │ │ │ │ │ │ ├── DailyScreenTimePieChart.kt │ │ │ │ │ │ └── StatisticsPieChartBase.kt │ │ │ │ │ ├── screenTime │ │ │ │ │ │ └── ScreenTimeStatisticsCard.kt │ │ │ │ │ └── tasks │ │ │ │ │ │ └── TasksStatisticsCard.kt │ │ │ │ ├── taskEntry │ │ │ │ │ ├── EntryType.kt │ │ │ │ │ ├── GroupedTaskEntries.kt │ │ │ │ │ ├── TaskEntry.kt │ │ │ │ │ ├── TaskEntryLabels.kt │ │ │ │ │ └── TaskInfoCard.kt │ │ │ │ └── taskLabelEntry │ │ │ │ │ ├── TaskLabelEntry.kt │ │ │ │ │ ├── TaskLabelPill.kt │ │ │ │ │ └── TaskLabelsEntryMode.kt │ │ │ │ ├── checkboxes │ │ │ │ └── RoundCheckbox.kt │ │ │ │ ├── dialogs │ │ │ │ ├── CircularProgressDialog.kt │ │ │ │ ├── DiscardPromptDialog.kt │ │ │ │ ├── FullScreenLoading.kt │ │ │ │ └── MultiplatformDialog.kt │ │ │ │ ├── images │ │ │ │ ├── AsyncImage.kt │ │ │ │ ├── ImageWithDescription.kt │ │ │ │ └── LottieAnimationWithDescription.kt │ │ │ │ ├── numberPicker │ │ │ │ ├── Converters.kt │ │ │ │ ├── HoursNumberPicker.kt │ │ │ │ ├── ListItemPicker.kt │ │ │ │ └── NumberPicker.kt │ │ │ │ ├── resources │ │ │ │ ├── AssetResourceExt.kt │ │ │ │ └── ComposeExt.kt │ │ │ │ ├── statsHelpers │ │ │ │ ├── GetPieChartSlices.kt │ │ │ │ ├── GetScreenTimeBarChartData.kt │ │ │ │ ├── GetWeeklyTasksBarChartData.kt │ │ │ │ └── StatsDispatcher.kt │ │ │ │ ├── tab │ │ │ │ ├── ReluctTabIndicator.kt │ │ │ │ └── TabEntry.kt │ │ │ │ ├── textfields │ │ │ │ ├── ReluctTextField.kt │ │ │ │ ├── search │ │ │ │ │ ├── MaterialSearchBar.kt │ │ │ │ │ └── ReluctSearchBar.kt │ │ │ │ └── texts │ │ │ │ │ ├── CardEntryLabels.kt │ │ │ │ │ ├── HighlightTextProps.kt │ │ │ │ │ ├── HighlightedText.kt │ │ │ │ │ └── HyperlinkText.kt │ │ │ │ ├── topBar │ │ │ │ ├── CollapsingToolbarBase.kt │ │ │ │ ├── ProfilePicture.kt │ │ │ │ ├── ReluctContentTopBar.kt │ │ │ │ ├── ReluctNavigationTopBar.kt │ │ │ │ ├── ReluctPageHeading.kt │ │ │ │ ├── ReluctSmallTopBar.kt │ │ │ │ ├── ReluctTopBarBase.kt │ │ │ │ └── toolbar │ │ │ │ │ ├── CollapsingToolbarState.kt │ │ │ │ │ └── scrollflags │ │ │ │ │ └── ScrollState.kt │ │ │ │ └── util │ │ │ │ ├── BarsVisibility.kt │ │ │ │ ├── BottomBarVisibilityHandler.kt │ │ │ │ ├── Color.kt │ │ │ │ ├── ColorPalette.kt │ │ │ │ ├── EditTitles.kt │ │ │ │ ├── FetchMoreDataHandler.kt │ │ │ │ ├── PlatformPaddings.kt │ │ │ │ ├── PreviewData.kt │ │ │ │ └── ScrollContext.kt │ │ └── resources │ │ │ └── MR │ │ │ ├── assets │ │ │ ├── account_data.svg │ │ │ ├── add_files.svg │ │ │ ├── alarms_and_reminders.svg │ │ │ ├── confirmed_phone_hand.svg │ │ │ ├── email_done.svg │ │ │ ├── email_opened.svg │ │ │ ├── empty.svg │ │ │ ├── file_search.svg │ │ │ ├── github_octo.svg │ │ │ ├── login_art.svg │ │ │ ├── no_tasks.svg │ │ │ ├── permissions_unlock.svg │ │ │ ├── profile_pic.svg │ │ │ ├── push_notifications.svg │ │ │ ├── screens_present.svg │ │ │ ├── stats_pie_chart.svg │ │ │ ├── theme_change.svg │ │ │ └── welcome_mobile.svg │ │ │ ├── base │ │ │ ├── plurals.xml │ │ │ └── strings.xml │ │ │ └── files │ │ │ ├── error_occurred.json │ │ │ ├── no_data.json │ │ │ ├── no_permission.json │ │ │ ├── no_task_animation.json │ │ │ ├── pay_success.json │ │ │ ├── payment_failed.json │ │ │ ├── search_animation.json │ │ │ └── task_saved.json │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── compose │ │ └── common │ │ └── components │ │ ├── dialogs │ │ └── MultiplatformDialog.kt │ │ ├── images │ │ ├── AsyncImage.kt │ │ └── LottieAnimationWithDescription.kt │ │ ├── resources │ │ ├── AssetResourceExt.kt │ │ └── ComposeExt.kt │ │ ├── statsHelpers │ │ └── StatsDispatcher.kt │ │ └── util │ │ ├── Color.kt │ │ ├── ColorPalette.kt │ │ └── PlatformPaddings.kt ├── date-time-picker │ ├── build.gradle.kts │ └── src │ │ ├── androidMain │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── compose │ │ │ └── common │ │ │ └── date │ │ │ └── time │ │ │ └── picker │ │ │ ├── core │ │ │ ├── ColorUtils.kt │ │ │ ├── DateTimeDialog.kt │ │ │ ├── DrawText.kt │ │ │ └── TextBounds.kt │ │ │ └── util │ │ │ └── Composables.kt │ │ ├── commonMain │ │ └── kotlin │ │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── compose │ │ │ └── common │ │ │ └── date │ │ │ └── time │ │ │ └── picker │ │ │ ├── core │ │ │ ├── ColorUtils.kt │ │ │ ├── DateTimeDialog.kt │ │ │ ├── DateTimeDialogButtonText.kt │ │ │ ├── DateTimeDialogState.kt │ │ │ ├── DrawText.kt │ │ │ └── TextBounds.kt │ │ │ ├── date │ │ │ ├── DatePicker.kt │ │ │ ├── DatePickerColors.kt │ │ │ ├── DatePickerDefaults.kt │ │ │ └── DatePickerState.kt │ │ │ ├── time │ │ │ ├── TimePicker.kt │ │ │ ├── TimePickerColors.kt │ │ │ ├── TimePickerDefaults.kt │ │ │ └── TimePickerState.kt │ │ │ └── util │ │ │ ├── Composables.kt │ │ │ └── Extensions.kt │ │ └── desktopMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── compose │ │ └── common │ │ └── date │ │ └── time │ │ └── picker │ │ ├── core │ │ ├── ColorUtils.kt │ │ ├── DateTimeDialog.kt │ │ ├── DrawText.kt │ │ └── TextBounds.kt │ │ └── util │ │ └── Composables.kt ├── pager │ ├── README.md │ ├── build.gradle.kts │ ├── detekt-baseline.xml │ └── src │ │ ├── androidMain │ │ └── AndroidManifest.xml │ │ └── commonMain │ │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── compose │ │ └── common │ │ └── pager │ │ ├── core │ │ ├── Pager.kt │ │ └── PagerState.kt │ │ ├── indicators │ │ ├── PagerIndicator.kt │ │ └── PagerTab.kt │ │ └── snapper │ │ ├── LazyList.kt │ │ ├── SnapperFlingBehavior.kt │ │ └── SnapperLog.kt └── theme │ ├── build.gradle.kts │ └── src │ ├── androidMain │ ├── AndroidManifest.xml │ └── kotlin │ │ └── work │ │ └── racka │ │ └── reluct │ │ └── compose │ │ └── common │ │ └── theme │ │ └── util │ │ ├── ColorSchemeUtils.kt │ │ └── FontResources.kt │ ├── commonMain │ ├── kotlin │ │ └── work │ │ │ └── racka │ │ │ └── reluct │ │ │ └── compose │ │ │ └── common │ │ │ └── theme │ │ │ ├── Color.kt │ │ │ ├── Dimens.kt │ │ │ ├── Shape.kt │ │ │ ├── Theme.kt │ │ │ ├── Type.kt │ │ │ └── util │ │ │ ├── ColorSchemeUtils.kt │ │ │ └── FontResources.kt │ └── resources │ │ └── font │ │ ├── lexenddeca_bold.ttf │ │ ├── lexenddeca_light.ttf │ │ ├── lexenddeca_medium.ttf │ │ ├── lexenddeca_regular.ttf │ │ └── lexenddeca_thin.ttf │ └── desktopMain │ └── kotlin │ └── work │ └── racka │ └── reluct │ └── compose │ └── common │ └── theme │ └── util │ ├── ColorSchemeUtils.kt │ └── FontResources.kt ├── config └── detekt │ ├── baseline.xml │ └── detekt.yml ├── desktop └── app │ ├── build.gradle.kts │ ├── compose-desktop.pro │ ├── detekt-baseline.xml │ └── src │ └── desktopMain │ ├── kotlin │ └── work │ │ └── racka │ │ └── reluct │ │ ├── BouncyRopes.kt │ │ ├── Main.kt │ │ ├── ProcessesProvider.kt │ │ └── ui │ │ ├── common │ │ └── ReluctSplitPane.kt │ │ ├── navigationComponents │ │ ├── core │ │ │ ├── DefaultMainAppComponent.kt │ │ │ ├── MainAppComponent.kt │ │ │ └── MainAppComponentUI.kt │ │ ├── graphs │ │ │ ├── goals │ │ │ │ ├── DefaultGoalsComponent.kt │ │ │ │ ├── GoalItemsComponentRouter.kt │ │ │ │ ├── GoalsComponent.kt │ │ │ │ ├── GoalsRootChildren.kt │ │ │ │ └── MainGoalsComponentRouter.kt │ │ │ ├── screenTime │ │ │ │ ├── AppScreenTimeItemsComponentRouter.kt │ │ │ │ ├── DefaultScreenTimeComponent.kt │ │ │ │ ├── MainScreenTimeComponentRouter.kt │ │ │ │ └── ScreenTimeComponent.kt │ │ │ └── tasks │ │ │ │ ├── DefaultTasksComponent.kt │ │ │ │ ├── MainTasksComponentRouter.kt │ │ │ │ ├── TaskItemsComponentsRouter.kt │ │ │ │ ├── TasksComponent.kt │ │ │ │ └── TasksRootChildren.kt │ │ ├── navrail │ │ │ └── ReluctNavigationRail.kt │ │ └── tabs │ │ │ ├── ReluctTabBar.kt │ │ │ ├── TabDefaults.kt │ │ │ └── TasksTabBar.kt │ │ └── screens │ │ ├── ComposeRenderer.kt │ │ ├── dashboard │ │ └── DashboardComponent.kt │ │ ├── goals │ │ ├── active │ │ │ ├── ActiveGoalsComponent.kt │ │ │ └── ActiveGoalsUI.kt │ │ ├── addEdit │ │ │ ├── AddEditGoalComponent.kt │ │ │ └── AddEditGoalUI.kt │ │ ├── components │ │ │ ├── AppsListCard.kt │ │ │ ├── DetailsCard.kt │ │ │ ├── EmptyGoalsIndicator.kt │ │ │ ├── NewGoalSheet.kt │ │ │ └── UpdateValueDialog.kt │ │ ├── details │ │ │ ├── GoalDetailsComponent.kt │ │ │ └── GoalDetailsUI.kt │ │ └── inactive │ │ │ ├── InactiveGoalsComponent.kt │ │ │ └── InactiveGoalsUI.kt │ │ ├── onBoarding │ │ └── OnBoardingComponent.kt │ │ ├── screenTime │ │ ├── appStats │ │ │ └── AppScreenTimeComponent.kt │ │ ├── components │ │ │ ├── AppNameEntry.kt │ │ │ ├── AppTimeLimitDialog.kt │ │ │ ├── AppTimeLimitUI.kt │ │ │ ├── FocusMode.kt │ │ │ ├── ManageAppsUI.kt │ │ │ ├── ScreenTimeWeekSelectorButton.kt │ │ │ └── UsagePermissionDialog.kt │ │ └── statsAndLimits │ │ │ └── ScreenTimeStatsLimitsComponent.kt │ │ ├── settings │ │ └── SettingsComponent.kt │ │ └── tasks │ │ ├── addEdit │ │ ├── AddEditTaskComponent.kt │ │ └── AddEditTaskUI.kt │ │ ├── completed │ │ ├── CompletedTasksComponent.kt │ │ └── CompletedTasksUI.kt │ │ ├── components │ │ ├── FullEmptyTasksIndicator.kt │ │ ├── ManageTaskLabelsSheet.kt │ │ └── ModifyTaskLabel.kt │ │ ├── details │ │ ├── TaskDetailsComponent.kt │ │ └── TaskDetailsUI.kt │ │ ├── pending │ │ ├── PendingTasksComponent.kt │ │ └── PendingTasksUI.kt │ │ ├── search │ │ ├── SearchTasksComponent.kt │ │ └── TasksSearchUI.kt │ │ └── statistics │ │ ├── TasksStatisticsComponent.kt │ │ └── TasksStatisticsUI.kt │ └── resources │ └── icons │ ├── app_icon_alt.svg │ ├── launcher │ ├── linux.png │ ├── macos.icns │ └── windows.ico │ └── window_icon.svg ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kotlin-js-store └── yarn.lock ├── settings.gradle.kts ├── web └── app │ ├── build.gradle.kts │ └── src │ └── main │ ├── kotlin │ └── work │ │ └── racka │ │ └── reluct │ │ ├── Client.kt │ │ └── ui │ │ ├── MaterialApp.kt │ │ ├── TestUI.kt │ │ ├── common │ │ ├── Area.kt │ │ ├── M3Theme.kt │ │ ├── MissedWrappers.kt │ │ ├── Sizes.kt │ │ └── Themes.kt │ │ ├── components │ │ ├── Content.kt │ │ ├── Header.kt │ │ ├── Menu.kt │ │ ├── ShowCasesModule.kt │ │ ├── Sidebar.kt │ │ ├── ThemeModule.kt │ │ └── showcases │ │ │ ├── Accordion.kt │ │ │ ├── Alert.kt │ │ │ ├── AppBar.kt │ │ │ ├── Autocomplete.kt │ │ │ ├── Avatar.kt │ │ │ ├── Backdrop.kt │ │ │ ├── Badges.kt │ │ │ ├── BottomNavaigation.kt │ │ │ ├── Breadcrumbs.kt │ │ │ ├── Buttons.kt │ │ │ ├── Cards.kt │ │ │ ├── Checkbox.kt │ │ │ ├── Chips.kt │ │ │ ├── Dialogs.kt │ │ │ ├── Drawers.kt │ │ │ ├── FloatingActionButton.kt │ │ │ ├── ImageList.kt │ │ │ ├── LinearProgress.kt │ │ │ ├── Links.kt │ │ │ ├── Lists.kt │ │ │ ├── Menus.kt │ │ │ ├── Pagination.kt │ │ │ ├── Paper.kt │ │ │ ├── Pickers.kt │ │ │ ├── Popover.kt │ │ │ ├── Popper.kt │ │ │ ├── RadioButtons.kt │ │ │ ├── Rating.kt │ │ │ ├── Selects.kt │ │ │ ├── Skeleton.kt │ │ │ ├── Slider.kt │ │ │ ├── Snackbars.kt │ │ │ ├── Steppers.kt │ │ │ ├── Switches.kt │ │ │ ├── Tables.kt │ │ │ ├── Tabs.kt │ │ │ ├── TextFields.kt │ │ │ ├── ToggleButton.kt │ │ │ └── Tooltips.kt │ │ ├── entities │ │ └── Showcase.kt │ │ └── hooks │ │ └── UseShowcases.kt │ └── resources │ ├── app_icon_alt.svg │ ├── avatar.png │ ├── favicon.ico │ ├── index.html │ └── style.css └── webpack.config.d └── polyfill.js /.githooks/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # hook script to verify code formatting and guidelines 4 | # also it will try to format code and add missing license headers to every kotlin file. 5 | 6 | echo "***** Run Code Analysis and Formatting ******" 7 | git stash -q --keep-index 8 | 9 | # ./gradlew spotlessApply - To be enabled later 10 | # ./gradlew check - To be enabled later 11 | #./gradlew detekt - To be enabled later 12 | 13 | status=$? 14 | 15 | git stash pop -q 16 | 17 | echo "***** Done with Code Analysis and Formatting ******" 18 | 19 | exit $status 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Device:** 27 | - Model: [Samsung S10, Google Pixel 5, Dell XPS 13, etc] 28 | - OS: [e.g. Android, Windows, macOS] 29 | - Version: [9.0, 10, 11, 12, 13, etc] 30 | - App version (in app settings): [1.0.0-alpha04] 31 | 32 | **Additional context** 33 | Add any other context about the problem here. 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /android/app/benchmark-rules.pro: -------------------------------------------------------------------------------- 1 | # Benchmark builds should not be obfuscated. 2 | -dontobfuscate -------------------------------------------------------------------------------- /android/app/release/output-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "artifactType": { 4 | "type": "APK", 5 | "kind": "Directory" 6 | }, 7 | "applicationId": "work.racka.reluct", 8 | "variantName": "release", 9 | "elements": [ 10 | { 11 | "type": "SINGLE", 12 | "filters": [], 13 | "attributes": [], 14 | "versionCode": 10, 15 | "versionName": "1.0.0-alpha09", 16 | "outputFile": "app-release.apk" 17 | } 18 | ], 19 | "elementType": "File" 20 | } -------------------------------------------------------------------------------- /android/app/src/androidTest/kotlin/work/racka/reluct/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("com.example.composetemplate", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /android/app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/android/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /android/app/src/main/kotlin/work/racka/reluct/ui/ReluctMainCompose.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.State 5 | import work.racka.reluct.android.navigation.navhost.AppNavHost 6 | import work.racka.reluct.android.navigation.util.SettingsCheck 7 | import work.racka.reluct.compose.common.theme.ReluctAppTheme 8 | 9 | @Composable 10 | fun ReluctMainCompose(themeValue: Int, settingsCheck: State) { 11 | ReluctAppTheme(theme = themeValue) { 12 | AppNavHost(settingsCheck = settingsCheck) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/branding_image_layer_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night-v31/splash_theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #99606060 4 | #CCFFFFFF 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/splash_theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | -------------------------------------------------------------------------------- /android/app/src/main/res/values-v31/splash_theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6167FF 4 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/splash_theme.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Reluct 3 | -------------------------------------------------------------------------------- /android/app/src/test/kotlin/work/racka/reluct/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /android/benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /android/benchmark/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /android/benchmark/src/main/java/work/racka/reluct/android/benchmark/util/UiDeviceHelpers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.benchmark.util 2 | 3 | import androidx.test.uiautomator.UiDevice 4 | 5 | fun UiDevice.delayUi(timeMillis: Long) = waitForWindowUpdate(null, timeMillis) 6 | -------------------------------------------------------------------------------- /android/navigation/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/navbar/NavBarElevation.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.navbar 2 | 3 | import androidx.compose.ui.unit.dp 4 | 5 | internal object NavBarElevation { 6 | val Level0 = 0.0.dp 7 | val Level1 = 1.0.dp 8 | val Level2 = 3.0.dp 9 | val Level3 = 6.0.dp 10 | val Level4 = 8.0.dp 11 | val Level5 = 12.0.dp 12 | } 13 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/toptabs/TabDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.toptabs 2 | 3 | data class TabDestination( 4 | val route: String, 5 | val name: String 6 | ) 7 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/toptabs/dashboard/DashboardTabDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.toptabs.dashboard 2 | 3 | import work.racka.reluct.common.core.navigation.composeDestinations.dashboard.DashboardOverviewDestination 4 | import work.racka.reluct.common.core.navigation.composeDestinations.dashboard.DashboardStatsDestination 5 | 6 | enum class DashboardTabDestination(val route: String) { 7 | Overview(route = DashboardOverviewDestination.route), 8 | Statistics(route = DashboardStatsDestination.route); 9 | } 10 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/toptabs/goals/GoalsTabDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.toptabs.goals 2 | 3 | import work.racka.reluct.common.core.navigation.composeDestinations.goals.ActiveGoalsDestination 4 | import work.racka.reluct.common.core.navigation.composeDestinations.goals.InactiveGoalsDestination 5 | 6 | enum class GoalsTabDestination(val route: String) { 7 | Active(route = ActiveGoalsDestination.route), 8 | Inactive(route = InactiveGoalsDestination.route); 9 | } 10 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/toptabs/screentime/ScreenTimeTabDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.toptabs.screentime 2 | 3 | import work.racka.reluct.common.core.navigation.composeDestinations.screentime.ScreenTimeLimitsDestination 4 | import work.racka.reluct.common.core.navigation.composeDestinations.screentime.ScreenTimeStatsDestination 5 | 6 | enum class ScreenTimeTabDestination(val route: String) { 7 | Statistics(route = ScreenTimeStatsDestination.route), 8 | Limits(route = ScreenTimeLimitsDestination.route); 9 | } 10 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/toptabs/tasks/TasksTabDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.toptabs.tasks 2 | 3 | import work.racka.reluct.common.core.navigation.composeDestinations.tasks.CompletedTasksDestination 4 | import work.racka.reluct.common.core.navigation.composeDestinations.tasks.PendingTasksDestination 5 | import work.racka.reluct.common.core.navigation.composeDestinations.tasks.TasksStatisticsDestination 6 | 7 | enum class TasksTabDestination(val route: String) { 8 | Tasks(route = PendingTasksDestination.route), 9 | Done(route = CompletedTasksDestination.route), 10 | Statistics(route = TasksStatisticsDestination.route); 11 | } 12 | -------------------------------------------------------------------------------- /android/navigation/src/main/kotlin/work/racka/reluct/android/navigation/util/SettingsCheck.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.navigation.util 2 | 3 | data class SettingsCheck( 4 | val isOnBoardingDone: Boolean, 5 | val showChangeLog: Boolean, 6 | val accountCheck: AccountCheck?, 7 | val loginSkipped: Boolean 8 | ) 9 | 10 | data class AccountCheck( 11 | val isEmailVerified: Boolean, 12 | val email: String 13 | ) 14 | -------------------------------------------------------------------------------- /android/navigation/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Done 3 | Tasks 4 | Statistics 5 | 6 | Statistics 7 | Limits 8 | 9 | Active 10 | Inactive 11 | 12 | Overview 13 | Statistics 14 | -------------------------------------------------------------------------------- /android/screens/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/screens/src/main/kotlin/work/racka/reluct/android/screens/tasks/components/ModifyTaskLabel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.screens.tasks.components 2 | 3 | import work.racka.reluct.common.model.domain.tasks.TaskLabel 4 | 5 | internal sealed class ModifyTaskLabel { 6 | class Delete(val label: TaskLabel) : ModifyTaskLabel() 7 | class SaveLabel(val label: TaskLabel) : ModifyTaskLabel() 8 | } 9 | -------------------------------------------------------------------------------- /android/screens/src/main/kotlin/work/racka/reluct/android/screens/util/BottomBarVisibilityHandler.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.android.screens.util 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.State 5 | import work.racka.reluct.compose.common.components.util.BarsVisibility 6 | import work.racka.reluct.compose.common.components.util.ScrollContext 7 | 8 | /** 9 | * A visibility handler that decides when to hide or show the bottom bar 10 | * This is defined as separate component to defer state reads and avoid recomposition 11 | */ 12 | @Composable 13 | internal fun BottomBarVisibilityHandler( 14 | scrollContext: State, 15 | barsVisibility: BarsVisibility, 16 | ) { 17 | if (scrollContext.value.isTop) { 18 | barsVisibility.bottomBar.show() 19 | } else { 20 | barsVisibility.bottomBar.hide() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/widgets/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /android/widgets/consumer-rules.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/android/widgets/consumer-rules.pro -------------------------------------------------------------------------------- /android/widgets/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /android/widgets/src/androidTest/java/work/racka/reluct/widgets/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets 2 | 3 | import androidx.test.ext.junit.runners.AndroidJUnit4 4 | import androidx.test.platform.app.InstrumentationRegistry 5 | import org.junit.Assert.assertEquals 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | /** 10 | * Instrumented test, which will execute on an Android device. 11 | * 12 | * See [testing documentation](http://d.android.com/tools/testing). 13 | */ 14 | @RunWith(AndroidJUnit4::class) 15 | class ExampleInstrumentedTest { 16 | @Test 17 | fun useAppContext() { 18 | // Context of the app under test. 19 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 20 | assertEquals("work.racka.reluct.widgets.test", appContext.packageName) 21 | } 22 | } -------------------------------------------------------------------------------- /android/widgets/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 11 | 12 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /android/widgets/src/main/java/work/racka/reluct/widgets/components/common/WidgetIconButton.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets.components.common 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.glance.GlanceModifier 5 | import androidx.glance.action.Action 6 | import androidx.glance.action.clickable 7 | import androidx.glance.layout.Alignment 8 | import androidx.glance.layout.Box 9 | 10 | @Composable 11 | fun WidgetIconButton( 12 | onClick: Action, 13 | icon: @Composable () -> Unit, 14 | modifier: GlanceModifier = GlanceModifier, 15 | ) { 16 | Box( 17 | modifier = GlanceModifier.clickable(onClick) then modifier, 18 | contentAlignment = Alignment.Center 19 | ) { 20 | icon() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /android/widgets/src/main/java/work/racka/reluct/widgets/core/PendingIntent.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets.core 2 | 3 | import android.app.PendingIntent 4 | import android.content.Context 5 | import android.content.Intent 6 | import androidx.core.app.TaskStackBuilder 7 | import androidx.core.net.toUri 8 | 9 | internal fun openDeepLinkPendingIntent(context: Context, uriString: String): PendingIntent? { 10 | val intent = Intent( 11 | Intent.ACTION_VIEW, 12 | uriString.toUri() 13 | ) 14 | return TaskStackBuilder.create(context).run { 15 | addNextIntentWithParentStack(intent) 16 | getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/widgets/src/main/java/work/racka/reluct/widgets/core/ReluctGlanceWidgetReceiver.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets.core 2 | 3 | import androidx.glance.appwidget.GlanceAppWidget 4 | import androidx.glance.appwidget.GlanceAppWidgetReceiver 5 | import org.koin.core.component.KoinComponent 6 | 7 | abstract class ReluctGlanceWidgetReceiver> : 8 | GlanceAppWidgetReceiver(), 9 | KoinComponent { 10 | 11 | override val glanceAppWidget: GlanceAppWidget 12 | get() = createWidget().apply { 13 | initiateLoad() 14 | } 15 | 16 | abstract fun createWidget(): T 17 | } 18 | -------------------------------------------------------------------------------- /android/widgets/src/main/java/work/racka/reluct/widgets/tasks/HelloWidget.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets.tasks 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.glance.appwidget.GlanceAppWidget 5 | import androidx.glance.appwidget.SizeMode 6 | import androidx.glance.text.Text 7 | 8 | class HelloWidget : GlanceAppWidget() { 9 | 10 | override val sizeMode: SizeMode 11 | get() = SizeMode.Exact 12 | 13 | @Composable 14 | override fun Content() { 15 | println("Hello Widget content called") 16 | Text(text = "Hello Widget") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /android/widgets/src/main/java/work/racka/reluct/widgets/tasks/HelloWidgetReceiver.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets.tasks 2 | 3 | import androidx.glance.appwidget.GlanceAppWidget 4 | import androidx.glance.appwidget.GlanceAppWidgetReceiver 5 | 6 | class HelloWidgetReceiver : GlanceAppWidgetReceiver() { 7 | 8 | override val glanceAppWidget: GlanceAppWidget 9 | get() = HelloWidget() 10 | } 11 | -------------------------------------------------------------------------------- /android/widgets/src/main/res/drawable/ic_round_refresh_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /android/widgets/src/main/res/drawable/pending_tasks_preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/android/widgets/src/main/res/drawable/pending_tasks_preview.png -------------------------------------------------------------------------------- /android/widgets/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #ff6167FF 4 | #ffBEC1FF 5 | #ffb64fc8 6 | 7 | #ff6167FF 8 | #ffBEC1FF 9 | 10 | #ffffffff 11 | #ff000000 12 | 13 | #FF3A3A3A 14 | #FFFFFFFF 15 | 16 | #ffF1F0F5 17 | #ff121212 18 | -------------------------------------------------------------------------------- /android/widgets/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Showing 10 recent Pending Tasks 4 | -------------------------------------------------------------------------------- /android/widgets/src/main/res/xml/pending_tasks_widget_info.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /android/widgets/src/main/res/xml/widget_hello_info.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /android/widgets/src/test/java/work/racka/reluct/widgets/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.widgets 2 | 3 | import org.junit.Assert.assertEquals 4 | import org.junit.Test 5 | 6 | /** 7 | * Example local unit test, which will execute on the development machine (host). 8 | * 9 | * See [testing documentation](http://d.android.com/tools/testing). 10 | */ 11 | class ExampleUnitTest { 12 | @Test 13 | fun addition_isCorrect() { 14 | assertEquals(4, 2 + 2) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /build-configs/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `kotlin-dsl` 3 | `kotlin-dsl-precompiled-script-plugins` 4 | } 5 | 6 | repositories { 7 | google() 8 | mavenCentral() 9 | gradlePluginPortal() 10 | } 11 | 12 | dependencies { 13 | implementation(libs.detekt.gradle.plugin) 14 | implementation(libs.android.gradle.plugin) 15 | implementation(libs.kotlin.gradle.plugin) 16 | } 17 | 18 | gradlePlugin { 19 | plugins { 20 | create("detekt.setup") { 21 | id = "detekt.setup" 22 | implementationClass = "quality.DetektSetup" 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /build-configs/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencyResolutionManagement { 2 | repositories { 3 | mavenCentral() 4 | } 5 | versionCatalogs { 6 | create("libs") { 7 | from(files("../gradle/libs.versions.toml")) 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /build-configs/src/main/kotlin/quality/detekt.gradle.kts: -------------------------------------------------------------------------------- 1 | import extensions.androidGradle 2 | import extensions.detektGradle 3 | import quality.DetektSetup 4 | 5 | val libs: VersionCatalog = extensions.getByType().named("libs") 6 | 7 | buildscript { 8 | repositories { 9 | gradlePluginPortal() 10 | google() 11 | } 12 | 13 | dependencies { 14 | classpath(libs.androidGradle) 15 | classpath(libs.detektGradle) 16 | } 17 | } 18 | 19 | plugins { 20 | id("io.gitlab.arturbosch.detekt") 21 | } 22 | 23 | project.beforeEvaluate { 24 | 25 | } 26 | 27 | fun helloConfig() { 28 | println("Hello") 29 | } -------------------------------------------------------------------------------- /common/app-usage-stats/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/androidMain/res/drawable/default_app_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/common/app-usage-stats/src/androidMain/res/drawable/default_app_icon.webp -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonMain/kotlin/work/racka/reluct/common/app/usage/stats/di/AppUsageStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.di 2 | 3 | import org.koin.core.KoinApplication 4 | import org.koin.dsl.module 5 | 6 | object AppUsageStats { 7 | 8 | fun KoinApplication.appUsageModules() = 9 | this.apply { 10 | modules( 11 | commonModule(), 12 | Platform.module() 13 | ) 14 | } 15 | 16 | private fun commonModule() = module { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonMain/kotlin/work/racka/reluct/common/app/usage/stats/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun module(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonMain/kotlin/work/racka/reluct/common/app/usage/stats/manager/UsageDataManager.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.manager 2 | 3 | import work.racka.reluct.common.app.usage.stats.model.DataAppUsageInfo 4 | import work.racka.reluct.common.app.usage.stats.model.DataUsageStats 5 | 6 | interface UsageDataManager { 7 | /** 8 | * Returns DataUsageStats that contains a list of DataAppUsageInfo sorted by 9 | * timeInForeground descending 10 | */ 11 | suspend fun getUsageStats(startTimeMillis: Long, endTimeMillis: Long): DataUsageStats 12 | 13 | /** 14 | * Returns DataAppUsageInfo for specified app package name in specified time range 15 | */ 16 | suspend fun getAppUsage( 17 | startTimeMillis: Long, 18 | endTimeMillis: Long, 19 | packageName: String 20 | ): DataAppUsageInfo 21 | } 22 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonMain/kotlin/work/racka/reluct/common/app/usage/stats/model/DataAppUsageInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.model 2 | 3 | data class DataAppUsageInfo( 4 | val packageName: String, 5 | var timeInForeground: Long = 0, 6 | var appLaunchCount: Int = 0, 7 | ) 8 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonMain/kotlin/work/racka/reluct/common/app/usage/stats/model/DataUsageStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.model 2 | 3 | data class DataUsageStats( 4 | val appsUsageList: List, 5 | val unlockCount: Long, 6 | ) 7 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonMain/kotlin/work/racka/reluct/common/app/usage/stats/util/Util.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.util 2 | 3 | import work.racka.reluct.common.app.usage.stats.model.DataAppUsageInfo 4 | 5 | fun Collection.sortByHighestForegroundTime(): List { 6 | return this.sortedByDescending { appInfo -> 7 | appInfo.timeInForeground 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/commonTest/kotlin/work/racka/reluct/common/app/usage/stats/util/TestData.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.util 2 | 3 | internal object TestData -------------------------------------------------------------------------------- /common/app-usage-stats/src/desktopMain/kotlin/work/racka/reluct/common/app/usage/stats/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.di 2 | 3 | import org.koin.core.module.Module 4 | import org.koin.dsl.module 5 | import work.racka.reluct.common.app.usage.stats.manager.DesktopUsageDataManager 6 | import work.racka.reluct.common.app.usage.stats.manager.UsageDataManager 7 | 8 | internal actual object Platform { 9 | actual fun module(): Module = module { 10 | single { DesktopUsageDataManager() } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/app-usage-stats/src/desktopMain/kotlin/work/racka/reluct/common/app/usage/stats/manager/DesktopUsageDataManager.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.app.usage.stats.manager 2 | 3 | import work.racka.reluct.common.app.usage.stats.model.DataAppUsageInfo 4 | import work.racka.reluct.common.app.usage.stats.model.DataUsageStats 5 | 6 | internal class DesktopUsageDataManager : UsageDataManager { 7 | 8 | override suspend fun getUsageStats(startTimeMillis: Long, endTimeMillis: Long): DataUsageStats { 9 | return DataUsageStats(emptyList(), 0) 10 | } 11 | 12 | override suspend fun getAppUsage( 13 | startTimeMillis: Long, 14 | endTimeMillis: Long, 15 | packageName: String 16 | ): DataAppUsageInfo { 17 | return DataAppUsageInfo(packageName, 0, 0) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/authentication/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/authentication/src/androidMain/kotlin/racka/reluct/common/authentication/mappers/AuthUser.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.mappers 2 | 3 | import com.google.firebase.auth.FirebaseUser 4 | import racka.reluct.common.authentication.models.AuthUser 5 | 6 | fun FirebaseUser.asAuthUser(): AuthUser = AuthUser( 7 | id = uid, 8 | displayName = displayName ?: "User", 9 | profilePicUrl = photoUrl?.toString(), 10 | email = email ?: "NO_EMAIL", 11 | isEmailVerified = isEmailVerified, 12 | ) 13 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/di/Authentication.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.di 2 | 3 | import org.koin.core.KoinApplication 4 | import org.koin.dsl.module 5 | 6 | object Authentication { 7 | fun KoinApplication.installModules() = apply { 8 | modules(commonModule(), Platform.installModule()) 9 | } 10 | 11 | private fun commonModule() = module { } 12 | } 13 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun installModule(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/extras/Messages.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.extras 2 | 3 | object Messages { 4 | const val LOGGED_IN = "You are already Logged In!" 5 | const val NOT_LOGGED_IN = "You are not Logged In!" 6 | const val BLANK_DETAILS = "Email and Password can not be blank" 7 | const val UNKNOWN_ERROR = "An Error Occurred!" 8 | const val EMAIL_SEND_FAILED = "Email not sent!" 9 | const val EMAIL_INVALID = "Profile Email not valid!" 10 | } 11 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/managers/ManageUser.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.managers 2 | 3 | import racka.reluct.common.authentication.models.AuthUser 4 | import work.racka.reluct.common.model.util.Resource 5 | 6 | interface ManageUser { 7 | fun getAuthUser(): AuthUser? 8 | fun logOut() 9 | suspend fun refreshUser(): Resource 10 | suspend fun updatePassword( 11 | oldPassword: String, 12 | newPassword: String 13 | ): Resource 14 | } 15 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/managers/UserAuthentication.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.managers 2 | 3 | import racka.reluct.common.authentication.models.AuthLoginUser 4 | import racka.reluct.common.authentication.models.AuthRegisterUser 5 | import racka.reluct.common.authentication.models.AuthUser 6 | import work.racka.reluct.common.model.util.Resource 7 | 8 | typealias IsVerified = Boolean 9 | 10 | interface UserAuthentication { 11 | suspend fun registerWithEmail(user: AuthRegisterUser): Resource 12 | suspend fun loginWithEmail(user: AuthLoginUser): Resource 13 | suspend fun sendVerificationEmail(user: AuthUser) 14 | suspend fun checkEmailVerification(): Resource 15 | suspend fun forgotPasswordEmail(email: String): Resource 16 | } 17 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/models/AuthLoginUser.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.models 2 | 3 | data class AuthLoginUser( 4 | val email: String, 5 | val password: String 6 | ) 7 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/models/AuthRegisterUser.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.models 2 | 3 | data class AuthRegisterUser( 4 | val displayName: String, 5 | val profilePicUrl: String?, 6 | val email: String, 7 | val password: String 8 | ) 9 | -------------------------------------------------------------------------------- /common/authentication/src/commonMain/kotlin/racka/reluct/common/authentication/models/AuthUser.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.models 2 | 3 | data class AuthUser( 4 | val id: String, 5 | val displayName: String, 6 | val profilePicUrl: String?, 7 | val email: String, 8 | val isEmailVerified: Boolean = false 9 | ) 10 | -------------------------------------------------------------------------------- /common/authentication/src/desktopMain/kotlin/racka/reluct/common/authentication/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.di 2 | 3 | import org.koin.core.module.Module 4 | import org.koin.dsl.module 5 | import racka.reluct.common.authentication.managers.DesktopManageUser 6 | import racka.reluct.common.authentication.managers.DesktopUserAuthentication 7 | import racka.reluct.common.authentication.managers.ManageUser 8 | import racka.reluct.common.authentication.managers.UserAuthentication 9 | 10 | internal actual object Platform { 11 | actual fun installModule(): Module = module { 12 | factory { 13 | DesktopUserAuthentication() 14 | } 15 | factory { 16 | DesktopManageUser() 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/authentication/src/desktopMain/kotlin/racka/reluct/common/authentication/managers/DesktopManageUser.kt: -------------------------------------------------------------------------------- 1 | package racka.reluct.common.authentication.managers 2 | 3 | import racka.reluct.common.authentication.models.AuthUser 4 | import work.racka.reluct.common.model.util.Resource 5 | 6 | internal class DesktopManageUser : ManageUser { 7 | override fun getAuthUser(): AuthUser? { 8 | return null 9 | } 10 | 11 | override fun logOut() { 12 | // TODO: "Not yet implemented" 13 | } 14 | 15 | override suspend fun refreshUser(): Resource { 16 | return Resource.Error(message = "Not Implemented") 17 | } 18 | 19 | override suspend fun updatePassword( 20 | oldPassword: String, 21 | newPassword: String 22 | ): Resource { 23 | return Resource.Error(message = "Not Implemented") 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/billing/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/billing/src/androidMain/kotlin/work/racka/reluct/common/billing/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.di 2 | 3 | import com.revenuecat.purchases.Purchases 4 | import kotlinx.coroutines.Dispatchers 5 | import org.koin.core.module.Module 6 | import org.koin.dsl.module 7 | import work.racka.reluct.common.billing.api.BillingApi 8 | import work.racka.reluct.common.billing.api.RevenueCatAndroid 9 | 10 | internal actual object Platform { 11 | actual fun module(): Module = module { 12 | single { 13 | RevenueCatAndroid( 14 | purchases = Purchases.sharedInstance, 15 | dispatcher = Dispatchers.IO 16 | ) 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/billing/src/androidMain/kotlin/work/racka/reluct/common/billing/products/ProductInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.products 2 | 3 | import com.revenuecat.purchases.Package 4 | 5 | actual class ProductInfo(val info: Package) { 6 | override fun equals(other: Any?): Boolean { 7 | return other?.let { item -> 8 | item is ProductInfo && item.info == this.info 9 | } ?: false 10 | } 11 | 12 | override fun hashCode(): Int { 13 | return info.hashCode() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /common/billing/src/androidMain/kotlin/work/racka/reluct/common/billing/revenuecat/PackageMapper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.revenuecat 2 | 3 | import com.revenuecat.purchases.Package 4 | import work.racka.reluct.common.billing.products.Product 5 | import work.racka.reluct.common.billing.products.ProductInfo 6 | import work.racka.reluct.common.billing.products.ProductOffered 7 | 8 | internal fun Package.asProduct() = Product( 9 | name = this.product.title, 10 | description = product.description, 11 | price = product.price, 12 | currencyCode = product.priceCurrencyCode, 13 | productInfo = ProductInfo(this), 14 | productOffered = ProductOffered( 15 | sku = packageType.getSku(), 16 | id = product.sku 17 | ) 18 | ) 19 | -------------------------------------------------------------------------------- /common/billing/src/androidMain/kotlin/work/racka/reluct/common/billing/revenuecat/ProductSkuHelper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.revenuecat 2 | 3 | import com.revenuecat.purchases.PackageType 4 | import work.racka.reluct.common.billing.products.Sku 5 | 6 | fun PackageType.getSku(): Sku = 7 | when (this) { 8 | PackageType.UNKNOWN -> Sku.InAppPurchase 9 | PackageType.CUSTOM -> Sku.InAppPurchase 10 | PackageType.LIFETIME -> Sku.InAppPurchase 11 | else -> Sku.Subscription 12 | } 13 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/api/BillingApi.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.api 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import work.racka.reluct.common.billing.products.Product 5 | import work.racka.reluct.common.billing.products.ProductOffered 6 | import work.racka.reluct.common.model.util.Resource 7 | 8 | interface BillingApi { 9 | suspend fun getProducts(filterProducts: List = listOf()): Resource> 10 | suspend fun purchaseProduct(item: Product): Resource 11 | 12 | /** This return type is temporary. TODO: Change this later 13 | * Will have to figure out the suitable return type when we add other platforms impl 14 | */ 15 | suspend fun updatePermission(): Resource 16 | } 17 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/di/Billing.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.di 2 | 3 | import org.koin.core.KoinApplication 4 | import org.koin.dsl.module 5 | 6 | object Billing { 7 | 8 | fun KoinApplication.install() = apply { 9 | modules(Platform.module(), commonModule()) 10 | } 11 | 12 | private fun commonModule() = module { } 13 | } 14 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun module(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/products/ProductInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.products 2 | 3 | expect class ProductInfo 4 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/products/ProductOffered.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.products 2 | 3 | data class ProductOffered( 4 | val sku: Sku, 5 | val id: String 6 | ) 7 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/products/Products.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.products 2 | 3 | object Products { 4 | val coffee1 = ProductOffered(sku = Sku.InAppPurchase, id = "coffee_1") 5 | val coffee2 = ProductOffered(sku = Sku.InAppPurchase, id = "coffee_2") 6 | val coffee3 = ProductOffered(sku = Sku.InAppPurchase, id = "coffee_3") 7 | } 8 | -------------------------------------------------------------------------------- /common/billing/src/commonMain/kotlin/work/racka/reluct/common/billing/products/Sku.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.products 2 | 3 | enum class Sku( 4 | val type: String 5 | ) { 6 | Subscription( 7 | type = "subs" 8 | ), 9 | InAppPurchase( 10 | type = "inapp" 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /common/billing/src/desktopMain/kotlin/work/racka/reluct/common/billing/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.di 2 | 3 | import org.koin.core.module.Module 4 | import org.koin.dsl.module 5 | import work.racka.reluct.common.billing.api.BillingApi 6 | import work.racka.reluct.common.billing.api.DesktopBilling 7 | 8 | internal actual object Platform { 9 | actual fun module(): Module = module { 10 | single { DesktopBilling() } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/billing/src/desktopMain/kotlin/work/racka/reluct/common/billing/products/ProductInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.billing.products 2 | 3 | actual class ProductInfo(val id: String) { 4 | override fun equals(other: Any?): Boolean { 5 | return other?.let { item -> 6 | item is ProductInfo && item.id == this.id 7 | } ?: false 8 | } 9 | 10 | override fun hashCode(): Int { 11 | return id.hashCode() 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/OtherDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object OtherDestination : NavDestination { 6 | private const val BASE_URI = "other_graph" 7 | override val route: String = "$BASE_URI-route" 8 | override val destination: String = "$BASE_URI-destination" 9 | } 10 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/dashboard/DashboardOverviewDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.dashboard 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object DashboardOverviewDestination : 6 | NavDestination { 7 | private const val BASE_URI = "dashboard_overview" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/dashboard/DashboardStatsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.dashboard 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object DashboardStatsDestination : 6 | NavDestination { 7 | private const val BASE_URI = "dashboard_statistics" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/goals/ActiveGoalsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.goals 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object ActiveGoalsDestination : 6 | NavDestination { 7 | private const val BASE_URI = "active_goals" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/goals/InactiveGoalsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.goals 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object InactiveGoalsDestination : 6 | NavDestination { 7 | private const val BASE_URI = "inactive_goals" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/onboarding/AuthenticationDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.onboarding 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object AuthenticationDestination : NavDestination { 6 | private const val BASE_URI = "authentication" 7 | override val route: String = "$BASE_URI-route" 8 | override val destination: String = "$BASE_URI-destination" 9 | } 10 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/onboarding/OnBoardingDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.onboarding 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object OnBoardingDestination : NavDestination { 6 | private const val BASE_URI = "on_boarding" 7 | override val route: String = "$BASE_URI-route" 8 | override val destination: String = "$BASE_URI-destination" 9 | } 10 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/screentime/ScreenTimeLimitsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.screentime 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object ScreenTimeLimitsDestination : 6 | NavDestination { 7 | private const val BASE_URI = "screen_time_limits" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/screentime/ScreenTimeStatsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.screentime 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object ScreenTimeStatsDestination : 6 | NavDestination { 7 | private const val BASE_URI = "screen_time_statistics" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/settings/ManageAccountDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.settings 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object ManageAccountDestination : NavDestination { 6 | private const val BASE_URI = "account-settings" 7 | override val route: String = "$BASE_URI-route" 8 | override val destination: String = "$BASE_URI-destination" 9 | } 10 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/settings/SettingsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.settings 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object SettingsDestination : NavDestination { 6 | private const val BASE_URI = "settings" 7 | override val route: String = "$BASE_URI-route" 8 | override val destination: String = "$BASE_URI-destination" 9 | } 10 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/tasks/CompletedTasksDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.tasks 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object CompletedTasksDestination : 6 | NavDestination { 7 | private const val BASE_URI = "completed_tasks" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/tasks/SearchTasksDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.tasks 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object SearchTasksDestination : 6 | NavDestination { 7 | private const val BASE_URI = "search_tasks" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/composeDestinations/tasks/TasksStatisticsDestination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.composeDestinations.tasks 2 | 3 | import work.racka.reluct.common.core.navigation.destination.NavDestination 4 | 5 | object TasksStatisticsDestination : 6 | NavDestination { 7 | private const val BASE_URI = "tasks_statistics" 8 | override val route: String = "$BASE_URI-route" 9 | override val destination: String = "$BASE_URI-destination" 10 | } 11 | -------------------------------------------------------------------------------- /common/core-navigation/src/androidMain/kotlin/work/racka/reluct/common/core/navigation/destination/NavDefaults.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.destination 2 | 3 | object NavDefaults { 4 | const val APP_DESTINATION_URI = "reluct://destinations" 5 | } 6 | -------------------------------------------------------------------------------- /common/core-navigation/src/commonMain/kotlin/work/racka/reluct/common/core/navigation/checks/InitialNavCheck.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.checks 2 | 3 | /** 4 | * Correct data is only guaranteed after [isChecking] is false. Please don't rely on this data 5 | * before that is complete. 6 | * 7 | * @param isChecking Still performing the check since its async. You are safe to access the other 8 | * params after [isChecking] is false 9 | * @param isOnBoardingDone Shows if on boarding flow was already done by the user 10 | * @param showChangeLog Shows if you should provide a changelog to user or not 11 | */ 12 | data class InitialNavCheck( 13 | val isChecking: Boolean = true, 14 | val isOnBoardingDone: Boolean = false, 15 | val showChangeLog: Boolean = false 16 | ) 17 | -------------------------------------------------------------------------------- /common/core-navigation/src/desktopMain/kotlin/work/racka/reluct/common/core/navigation/destination/graphs/GoalsConfig.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.destination.graphs 2 | 3 | import com.arkivanov.essenty.parcelable.Parcelable 4 | 5 | sealed class GoalsConfig : Parcelable { 6 | object Active : GoalsConfig() 7 | object Inactive : GoalsConfig() 8 | } 9 | 10 | sealed class GoalsExtrasConfig : Parcelable { 11 | object None : GoalsExtrasConfig() 12 | data class AddEdit(val goalId: String?, val defaultGoalIndex: Int?) : GoalsExtrasConfig() 13 | data class Details(val goalId: String?) : GoalsExtrasConfig() 14 | } 15 | -------------------------------------------------------------------------------- /common/core-navigation/src/desktopMain/kotlin/work/racka/reluct/common/core/navigation/destination/graphs/ScreenTimeConfig.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.destination.graphs 2 | 3 | import com.arkivanov.essenty.parcelable.Parcelable 4 | 5 | sealed class ScreenTimeConfig : Parcelable { 6 | object StatsAndLimits : ScreenTimeConfig() 7 | } 8 | 9 | sealed class AppScreenTimeConfig : Parcelable { 10 | object None : AppScreenTimeConfig() 11 | data class App(val packageName: String?) : AppScreenTimeConfig() 12 | } 13 | -------------------------------------------------------------------------------- /common/core-navigation/src/desktopMain/kotlin/work/racka/reluct/common/core/navigation/destination/graphs/TasksConfig.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.core.navigation.destination.graphs 2 | 3 | import com.arkivanov.essenty.parcelable.Parcelable 4 | 5 | sealed class TasksConfig : Parcelable { 6 | object Completed : TasksConfig() 7 | object Pending : TasksConfig() 8 | object Search : TasksConfig() 9 | object Statistics : TasksConfig() 10 | } 11 | 12 | sealed class TasksExtraConfig : Parcelable { 13 | object None : TasksExtraConfig() 14 | data class AddEdit(val taskId: String?) : TasksExtraConfig() 15 | data class Details(val taskId: String?) : TasksExtraConfig() 16 | } 17 | -------------------------------------------------------------------------------- /common/di-integration/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /common/domain/src/androidMain/kotlin/work/racka/reluct/common/domain/alarms/AlarmsKeys.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.alarms 2 | 3 | import work.racka.reluct.common.services.util.IntentData 4 | 5 | internal object AlarmsKeys { 6 | val TASK_REMINDER = IntentData(action = "TASK_REMINDER_ACTION", key = "TASK_REMINDER_KEY") 7 | } 8 | -------------------------------------------------------------------------------- /common/domain/src/androidMain/kotlin/work/racka/reluct/common/domain/di/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.di 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual object CoroutineDispatchers { 7 | actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO 8 | } 9 | -------------------------------------------------------------------------------- /common/domain/src/androidMain/res/drawable/ic_baseline_fact_check_24.xml: -------------------------------------------------------------------------------- 1 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /common/domain/src/androidMain/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Tasks Reminders 4 | All Tasks Reminders set from the app 5 | Upcoming Task: %1$s 6 | Description: %1$s 7 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/di/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.di 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | 5 | expect object CoroutineDispatchers { 6 | val backgroundDispatcher: CoroutineDispatcher 7 | } 8 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun installModule(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/mappers/tasks/TaskLabel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.mappers.tasks 2 | 3 | import work.racka.reluct.common.database.models.TaskLabelDbObject 4 | import work.racka.reluct.common.model.domain.tasks.TaskLabel 5 | 6 | fun TaskLabelDbObject.asTaskLabel() = TaskLabel( 7 | id = id, 8 | name = name, 9 | description = description, 10 | colorHexString = colorHexString 11 | ) 12 | 13 | fun TaskLabel.asTaskLabelDbObject() = TaskLabelDbObject( 14 | id = id, 15 | name = name, 16 | description = description, 17 | colorHexString = colorHexString 18 | ) 19 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/mappers/usagestats/AppUsageInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.mappers.usagestats 2 | 3 | import work.racka.reluct.common.app.usage.stats.model.DataAppUsageInfo 4 | import work.racka.reluct.common.domain.usecases.appInfo.GetAppInfo 5 | import work.racka.reluct.common.model.domain.usagestats.AppUsageInfo 6 | import work.racka.reluct.common.model.util.time.TimeUtils 7 | 8 | suspend fun DataAppUsageInfo.asAppUsageInfo(getAppInfo: GetAppInfo): AppUsageInfo = AppUsageInfo( 9 | packageName = this.packageName, 10 | appName = getAppInfo.getAppName(packageName), 11 | appIcon = getAppInfo.getAppIcon(packageName), 12 | timeInForeground = this.timeInForeground, 13 | formattedTimeInForeground = TimeUtils 14 | .getFormattedTimeDurationString(this.timeInForeground), 15 | appLaunchCount = this.appLaunchCount 16 | ) 17 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/pagination/Paginator.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.pagination 2 | 3 | interface Paginator { 4 | suspend fun loadNextItems() 5 | fun reset() 6 | } 7 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/appInfo/GetAppInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.appInfo 2 | 3 | import work.racka.reluct.common.model.domain.core.Icon 4 | 5 | interface GetAppInfo { 6 | suspend fun getAppIcon(packageName: String): Icon 7 | suspend fun getAppName(packageName: String): String 8 | } 9 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/appInfo/GetInstalledApps.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.appInfo 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import work.racka.reluct.common.model.domain.appInfo.AppInfo 5 | 6 | interface GetInstalledApps { 7 | suspend fun invoke(): ImmutableList 8 | } 9 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/appUsage/GetAppUsageInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.appUsage 2 | 3 | import kotlinx.collections.immutable.ImmutableMap 4 | import work.racka.reluct.common.model.domain.usagestats.AppUsageStats 5 | import work.racka.reluct.common.model.util.time.Week 6 | 7 | interface GetAppUsageInfo { 8 | suspend fun dailUsage( 9 | weekOffset: Int = 0, 10 | dayIsoNumber: Int, 11 | packageName: String 12 | ): AppUsageStats 13 | 14 | suspend fun weeklyUsage(weekOffset: Int, packageName: String): ImmutableMap 15 | } 16 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/appUsage/GetUsageStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.appUsage 2 | 3 | import kotlinx.collections.immutable.ImmutableMap 4 | import work.racka.reluct.common.model.domain.usagestats.UsageStats 5 | import work.racka.reluct.common.model.util.time.Week 6 | 7 | interface GetUsageStats { 8 | suspend fun dailyUsage(weekOffset: Int = 0, dayIsoNumber: Int): UsageStats 9 | suspend fun weeklyUsage(weekOffset: Int = 0): ImmutableMap 10 | } 11 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/authentication/LoginSignupUser.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.authentication 2 | 3 | import work.racka.reluct.common.model.domain.authentication.EmailUserLogin 4 | import work.racka.reluct.common.model.domain.authentication.RegisterUser 5 | import work.racka.reluct.common.model.domain.authentication.User 6 | import work.racka.reluct.common.model.util.Resource 7 | 8 | interface LoginSignupUser { 9 | suspend fun emailLogin(login: EmailUserLogin): Resource 10 | suspend fun emailSignup(register: RegisterUser): Resource 11 | suspend fun checkEmailVerification(): Boolean 12 | suspend fun sendVerificationEmail(user: User) 13 | } 14 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/authentication/UserAccountManagement.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.authentication 2 | 3 | import work.racka.reluct.common.model.domain.authentication.User 4 | import work.racka.reluct.common.model.util.Resource 5 | 6 | interface UserAccountManagement { 7 | fun getUser(): User? 8 | fun logout() 9 | suspend fun refreshUser(): Resource 10 | suspend fun updatePassword(oldPassword: String, newPassword: String): Resource 11 | 12 | /** 13 | * Returns the [email] on success 14 | */ 15 | suspend fun requestPasswordResetEmail(email: String): Resource 16 | } 17 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/billing/ManageCoffeeProducts.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.billing 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import work.racka.reluct.common.billing.api.BillingApi 5 | import work.racka.reluct.common.billing.products.Product 6 | import work.racka.reluct.common.model.util.Resource 7 | 8 | interface ManageCoffeeProducts { 9 | val api: BillingApi // Direct access to the API 10 | suspend fun getAllProducts(): Resource> 11 | } 12 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/goals/GetGoals.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.goals 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.coroutines.flow.Flow 5 | import work.racka.reluct.common.model.domain.goals.Goal 6 | 7 | interface GetGoals { 8 | fun getActiveGoals(factor: Long, limitBy: Long = 10): Flow> 9 | fun getInActiveGoals(factor: Long, limitBy: Long = 10): Flow> 10 | fun getGoal(id: String): Flow 11 | suspend fun getGoalSync(id: String): Goal? 12 | } 13 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/goals/ModifyGoals.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.goals 2 | 3 | import work.racka.reluct.common.model.domain.goals.Goal 4 | 5 | interface ModifyGoals { 6 | suspend fun saveGoal(goal: Goal) 7 | suspend fun deleteGoal(id: String) 8 | suspend fun toggleGoalActiveState(isActive: Boolean, id: String) 9 | suspend fun updateGoalCurrentValue(id: String, currentValue: Long) 10 | suspend fun syncGoals() 11 | } 12 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/GetAppLimits.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | import work.racka.reluct.common.model.domain.limits.AppLimits 5 | 6 | interface GetAppLimits { 7 | fun getApp(packageName: String): Flow 8 | suspend fun getAppSync(packageName: String): AppLimits 9 | } 10 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/GetDistractingApps.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.coroutines.flow.Flow 5 | import work.racka.reluct.common.model.domain.limits.AppLimits 6 | 7 | interface GetDistractingApps { 8 | fun getApps(): Flow> 9 | 10 | suspend fun getSync(): ImmutableList 11 | 12 | suspend fun isDistractingApp(packageName: String): Boolean 13 | } 14 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/GetPausedApps.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.coroutines.flow.Flow 5 | import work.racka.reluct.common.model.domain.limits.AppLimits 6 | 7 | interface GetPausedApps { 8 | fun getApps(): Flow> 9 | 10 | suspend fun getSync(): ImmutableList 11 | 12 | suspend fun isPaused(packageName: String): Boolean 13 | } 14 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/ManageAppTimeLimit.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | import work.racka.reluct.common.model.domain.limits.AppTimeLimit 5 | 6 | interface ManageAppTimeLimit { 7 | /** 8 | * Get the specified app packageName time Limit as a Flow 9 | */ 10 | fun getLimit(packageName: String): Flow 11 | 12 | /** 13 | * Get the specified app packageName time Limit synchronously 14 | */ 15 | suspend fun getSync(packageName: String): AppTimeLimit 16 | 17 | suspend fun setTimeLimit(appTimeLimit: AppTimeLimit) 18 | } 19 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/ManageFocusMode.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | 5 | interface ManageFocusMode { 6 | val isFocusModeOn: Flow 7 | val isDoNotDisturbOn: Flow 8 | val isAppBlockingEnabled: Flow 9 | 10 | suspend fun toggleFocusMode(isFocusMode: Boolean) 11 | suspend fun toggleDoNoDisturb(isDnd: Boolean) 12 | } 13 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/ManagePausedApps.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.coroutines.flow.Flow 5 | import work.racka.reluct.common.model.domain.appInfo.AppInfo 6 | 7 | interface ManagePausedApps { 8 | /** 9 | * Returns a [Flow] of pair of two Lists typed [AppInfo] 10 | * The first value of the pair is a list of Paused apps 11 | * The second value of the pair is a list of Non Paused Apps present in the user device 12 | */ 13 | fun getApps(): Flow, ImmutableList>> 14 | 15 | suspend fun pauseApp(packageName: String) 16 | suspend fun unPauseApp(packageName: String) 17 | suspend fun isPaused(packageName: String): Boolean 18 | } 19 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/limits/ModifyAppLimits.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.limits 2 | 3 | import work.racka.reluct.common.model.domain.limits.AppLimits 4 | 5 | interface ModifyAppLimits { 6 | suspend fun insertApp(appLimits: AppLimits) 7 | suspend fun removeApp(packageName: String) 8 | suspend fun removeAllApp(packageName: String) 9 | suspend fun resumeAllApps() 10 | suspend fun setLimit(packageName: String, timeLimit: Long) 11 | suspend fun pauseApp(packageName: String, isPaused: Boolean) 12 | suspend fun makeDistractingApp(packageName: String, isDistracting: Boolean) 13 | suspend fun overrideLimit(packageName: String, overridden: Boolean) 14 | } 15 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/tasks/GetGroupedTasksStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.tasks 2 | 3 | import kotlinx.collections.immutable.ImmutableMap 4 | import kotlinx.coroutines.flow.Flow 5 | import work.racka.reluct.common.model.domain.tasks.DailyTasksStats 6 | import work.racka.reluct.common.model.util.time.Week 7 | 8 | interface GetGroupedTasksStats { 9 | fun dailyTasks(weekOffset: Int = 0, dayIsoNumber: Int): Flow 10 | fun weeklyTasks(weekOffset: Int = 0): Flow> 11 | fun timeRangeTasks(timeRangeMillis: LongRange): Flow 12 | } 13 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/tasks/ManageTaskLabels.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.tasks 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.coroutines.flow.Flow 5 | import work.racka.reluct.common.model.domain.tasks.TaskLabel 6 | 7 | interface ManageTaskLabels { 8 | suspend fun addLabel(label: TaskLabel) 9 | suspend fun addLabels(labels: ImmutableList) 10 | 11 | fun allLabels(): Flow> 12 | fun getLabel(id: String): Flow 13 | 14 | suspend fun deleteLabel(id: String) 15 | suspend fun deleteAllLabels() 16 | } 17 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/tasks/ManageTasksAlarms.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.tasks 2 | 3 | import kotlinx.datetime.LocalDateTime 4 | 5 | interface ManageTasksAlarms { 6 | suspend fun setAlarm(taskId: String, dateTime: LocalDateTime) 7 | suspend fun removeAlarm(taskId: String) 8 | suspend fun rescheduleAlarms() 9 | } 10 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/tasks/ModifyTaskUseCase.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.tasks 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | import work.racka.reluct.common.model.domain.tasks.EditTask 5 | import work.racka.reluct.common.model.domain.tasks.Task 6 | 7 | interface ModifyTaskUseCase { 8 | fun getTaskToEdit(taskId: String): Flow 9 | suspend fun saveTask(task: EditTask) 10 | suspend fun deleteTask(taskId: String) 11 | suspend fun toggleTaskDone(task: Task, isDone: Boolean) 12 | } 13 | -------------------------------------------------------------------------------- /common/domain/src/commonMain/kotlin/work/racka/reluct/common/domain/usecases/time/GetWeekRangeFromOffset.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.time 2 | 3 | interface GetWeekRangeFromOffset { 4 | suspend fun invoke(weekOffset: Int): String 5 | } 6 | -------------------------------------------------------------------------------- /common/domain/src/desktopMain/kotlin/work/racka/reluct/common/domain/di/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.di 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual object CoroutineDispatchers { 7 | actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO 8 | } 9 | -------------------------------------------------------------------------------- /common/domain/src/desktopMain/kotlin/work/racka/reluct/common/domain/usecases/appInfo/DesktopGetAppInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.appInfo 2 | 3 | import work.racka.reluct.common.model.domain.core.Icon 4 | 5 | internal class DesktopGetAppInfo : GetAppInfo { 6 | override suspend fun getAppIcon(packageName: String): Icon { 7 | return Icon(byteArrayOf(0)) 8 | } 9 | 10 | override suspend fun getAppName(packageName: String): String { 11 | return packageName 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/domain/src/desktopMain/kotlin/work/racka/reluct/common/domain/usecases/appInfo/DesktopGetInstalledApps.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.appInfo 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.collections.immutable.persistentListOf 5 | import work.racka.reluct.common.model.domain.appInfo.AppInfo 6 | 7 | internal class DesktopGetInstalledApps : GetInstalledApps { 8 | override suspend fun invoke(): ImmutableList { 9 | return persistentListOf() 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /common/domain/src/desktopMain/kotlin/work/racka/reluct/common/domain/usecases/tasks/DesktopManageTasksAlarms.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.domain.usecases.tasks 2 | 3 | import kotlinx.datetime.LocalDateTime 4 | 5 | internal class DesktopManageTasksAlarms : ManageTasksAlarms { 6 | override suspend fun setAlarm(taskId: String, dateTime: LocalDateTime) { 7 | // Not implemented yet 8 | } 9 | 10 | override suspend fun removeAlarm(taskId: String) { 11 | // Not Implemented yet 12 | } 13 | 14 | override suspend fun rescheduleAlarms() { 15 | // Not Implemented yet 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common/features/dashboard/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/features/dashboard/src/commonMain/kotlin/work/racka/reluct/common/features/dashboard/overview/states/DashboardEvents.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.dashboard.overview.states 2 | 3 | sealed class DashboardEvents { 4 | object Nothing : DashboardEvents() 5 | data class ShowMessageDone(val isDone: Boolean, val msg: String) : DashboardEvents() 6 | } 7 | -------------------------------------------------------------------------------- /common/features/goals/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/features/goals/src/commonMain/kotlin/work/racka/reluct/common/features/goals/active/states/ActiveGoalsState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.goals.active.states 2 | 3 | data class ActiveGoalsState( 4 | val isSyncing: Boolean = false, 5 | val goalsListState: GoalsListState = GoalsListState.Loading() 6 | ) 7 | -------------------------------------------------------------------------------- /common/features/goals/src/commonMain/kotlin/work/racka/reluct/common/features/goals/active/states/GoalsEvents.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.goals.active.states 2 | 3 | sealed class GoalsEvents { 4 | object Nothing : GoalsEvents() 5 | class GoalSavedMessage(val goalName: String) : GoalsEvents() 6 | class ChangedGoalState(val isActive: Boolean, val msg: String) : GoalsEvents() 7 | class DeletedGoal(val goalId: String, val goalName: String) : GoalsEvents() 8 | object Exit : GoalsEvents() 9 | } 10 | -------------------------------------------------------------------------------- /common/features/goals/src/commonMain/kotlin/work/racka/reluct/common/features/goals/details/states/GoalDetailsState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.goals.details.states 2 | 3 | import work.racka.reluct.common.model.domain.goals.Goal 4 | 5 | sealed class GoalDetailsState(val isSyncing: Boolean) { 6 | data class Data( 7 | val goal: Goal, 8 | private val syncingData: Boolean 9 | ) : GoalDetailsState(syncingData) 10 | 11 | object NotFound : GoalDetailsState(false) 12 | object Loading : GoalDetailsState(false) 13 | } 14 | -------------------------------------------------------------------------------- /common/features/onboarding/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/features/onboarding/src/commonMain/kotlin/work/racka/reluct/common/features/onboarding/states/auth/LoginSignupEvent.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.onboarding.states.auth 2 | 3 | sealed class LoginSignupEvent { 4 | class LoginError(val attempts: Int, val message: String) : LoginSignupEvent() 5 | class SignupError(val email: String, val message: String) : LoginSignupEvent() 6 | class Error(val message: String) : LoginSignupEvent() 7 | object Continue : LoginSignupEvent() 8 | object None : LoginSignupEvent() 9 | } 10 | -------------------------------------------------------------------------------- /common/features/onboarding/src/commonMain/kotlin/work/racka/reluct/common/features/onboarding/states/onBoarding/PermissionType.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.onboarding.states.onBoarding 2 | 3 | enum class PermissionType { 4 | NOTIFICATION, REMINDERS, USAGE_ACCESS, OVERLAY 5 | } 6 | -------------------------------------------------------------------------------- /common/features/screen-time/src/androidMain/res/drawable/ic_twotone_aod_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /common/features/screen-time/src/commonMain/kotlin/work/racka/reluct/common/features/screenTime/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun installModule(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/features/screen-time/src/commonMain/kotlin/work/racka/reluct/common/features/screenTime/limits/states/AppTimeLimitState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.limits.states 2 | 3 | import work.racka.reluct.common.model.domain.limits.AppTimeLimit 4 | 5 | sealed class AppTimeLimitState { 6 | object Nothing : AppTimeLimitState() 7 | object Loading : AppTimeLimitState() 8 | data class Data(val timeLimit: AppTimeLimit) : AppTimeLimitState() 9 | } 10 | -------------------------------------------------------------------------------- /common/features/screen-time/src/commonMain/kotlin/work/racka/reluct/common/features/screenTime/services/ScreenTimeServices.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.services 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | 5 | interface ScreenTimeServices { 6 | suspend fun startLimitsService() 7 | fun stopLimitsService() 8 | fun observeCurrentAppBlocking(): Flow 9 | 10 | sealed class BlockState(val appPackageName: String) { 11 | class Blocked(appPackageName: String) : BlockState(appPackageName) 12 | class Allowed(appPackageName: String) : BlockState(appPackageName) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/features/screen-time/src/commonMain/kotlin/work/racka/reluct/common/features/screenTime/statistics/states/ScreenTimeStatsEvents.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.statistics.states 2 | 3 | import work.racka.reluct.common.model.domain.limits.AppTimeLimit 4 | 5 | sealed class ScreenTimeStatsEvents { 6 | object Nothing : ScreenTimeStatsEvents() 7 | data class ShowMessageDone(val isDone: Boolean, val msg: String) : ScreenTimeStatsEvents() 8 | class TimeLimitChange(val app: AppTimeLimit) : ScreenTimeStatsEvents() 9 | 10 | sealed class Navigation : ScreenTimeStatsEvents() { 11 | data class NavigateToAppInfo( 12 | val packageName: String 13 | ) : Navigation() 14 | 15 | data class OpenAppTimerSettings( 16 | val packageName: String 17 | ) : Navigation() 18 | 19 | object GoBack : Navigation() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/features/screen-time/src/commonMain/kotlin/work/racka/reluct/common/features/screenTime/statistics/states/ScreenTimeStatsSelectedInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.statistics.states 2 | 3 | data class ScreenTimeStatsSelectedInfo( 4 | val weekOffset: Int = 0, 5 | val selectedWeekText: String = "...", 6 | val selectedDay: Int = 0 7 | ) 8 | -------------------------------------------------------------------------------- /common/features/screen-time/src/commonMain/kotlin/work/racka/reluct/common/features/screenTime/util/Constants.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.util 2 | 3 | internal object Constants { 4 | const val MARK_DISTRACTING = "Marked As Distracting" 5 | const val UN_MARK_DISTRACTING = "Marked As Not Distracting" 6 | const val MARK_PAUSED = "App has been paused" 7 | const val UN_MARK_PAUSED = "App has been resumed" 8 | const val FOCUS_MODE_ON = "Focus Mode Turned On" 9 | const val FOCUS_MODE_OFF = "Focus Mode Turned Off" 10 | const val DND_ON = "Do Not Disturb Turned On" 11 | const val DND_OFF = "Do Not Disturb Turned Off" 12 | } 13 | -------------------------------------------------------------------------------- /common/features/screen-time/src/desktopMain/kotlin/work/racka/reluct/common/features/screenTime/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.di 2 | 3 | import org.koin.core.module.Module 4 | import org.koin.dsl.module 5 | import work.racka.reluct.common.features.screenTime.services.DesktopScreenTimeServices 6 | import work.racka.reluct.common.features.screenTime.services.ScreenTimeServices 7 | 8 | internal actual object Platform { 9 | actual fun installModule(): Module = module { 10 | factory { 11 | DesktopScreenTimeServices() 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/features/screen-time/src/desktopMain/kotlin/work/racka/reluct/common/features/screenTime/services/DesktopScreenTimeServices.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.screenTime.services 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | import kotlinx.coroutines.flow.flowOf 5 | 6 | internal class DesktopScreenTimeServices : ScreenTimeServices { 7 | override suspend fun startLimitsService() { /** DESKTOP IMPL **/ } 8 | 9 | override fun stopLimitsService() { /** DESKTOP IMPL **/ } 10 | 11 | override fun observeCurrentAppBlocking(): Flow { 12 | return flowOf() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/features/settings/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/features/settings/src/commonMain/kotlin/work/racka/reluct/common/features/settings/states/SettingsEvents.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.settings.states 2 | 3 | import work.racka.reluct.common.billing.products.Product 4 | 5 | sealed class SettingsEvents { 6 | object Nothing : SettingsEvents() 7 | class ThemeChanged(val themeValue: Int) : SettingsEvents() 8 | class FocusModeChanged(val isEnabled: Boolean) : SettingsEvents() 9 | class DndChanged(val isEnabled: Boolean) : SettingsEvents() 10 | class AppBlockingChanged(val isEnabled: Boolean) : SettingsEvents() 11 | class InitiatePurchase(val product: Product) : SettingsEvents() 12 | } 13 | -------------------------------------------------------------------------------- /common/features/settings/src/commonMain/kotlin/work/racka/reluct/common/features/settings/states/UserAccountEvents.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.settings.states 2 | 3 | sealed class UserAccountEvents { 4 | object None : UserAccountEvents() 5 | object RefreshFailed : UserAccountEvents() 6 | class PasswordReset(val success: Boolean) : UserAccountEvents() 7 | } 8 | -------------------------------------------------------------------------------- /common/features/settings/src/commonMain/kotlin/work/racka/reluct/common/features/settings/states/UserAccountState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.settings.states 2 | 3 | import work.racka.reluct.common.model.domain.authentication.User 4 | 5 | sealed class UserAccountState { 6 | data class Account(val user: User, val isUpdating: Boolean = false) : UserAccountState() 7 | object NotSignedIn : UserAccountState() 8 | object Updating : UserAccountState() 9 | } 10 | -------------------------------------------------------------------------------- /common/features/tasks/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/features/tasks/src/commonMain/kotlin/work/racka/reluct/common/features/tasks/states/TaskDetailsState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.tasks.states 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.collections.immutable.persistentListOf 5 | import work.racka.reluct.common.model.domain.tasks.Task 6 | import work.racka.reluct.common.model.domain.tasks.TaskLabel 7 | 8 | data class TaskDetailsState( 9 | val taskState: TaskState = TaskState.Loading, 10 | val availableTaskLabels: ImmutableList = persistentListOf() 11 | ) 12 | 13 | sealed class TaskState { 14 | object Loading : TaskState() 15 | object NotFound : TaskState() 16 | object Deleted : TaskState() 17 | data class Data(val task: Task) : TaskState() 18 | } 19 | -------------------------------------------------------------------------------- /common/features/tasks/src/commonMain/kotlin/work/racka/reluct/common/features/tasks/util/Constants.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.features.tasks.util 2 | 3 | internal object Constants { 4 | const val TASK_NOT_FOUND = "Can't find this Task in Database!" 5 | const val DELETED_SUCCESSFULLY = "Task has been deleted successfully" 6 | const val TASK_DONE = "Task Completed" 7 | const val TASK_NOT_DONE = "Task Marked As Incomplete" 8 | const val TASK_SAVED = "Task Saved Successfully" 9 | } 10 | -------------------------------------------------------------------------------- /common/model/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/model/src/androidMain/kotlin/work/racka/reluct/common/model/domain/core/Icon.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.core 2 | 3 | import android.graphics.drawable.Drawable 4 | 5 | actual class Icon( 6 | val icon: Drawable 7 | ) 8 | -------------------------------------------------------------------------------- /common/model/src/androidMain/kotlin/work/racka/reluct/common/model/util/UUIDGen.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.util 2 | 3 | import java.util.* 4 | 5 | actual object UUIDGen { 6 | actual fun getString(): String = UUID.randomUUID().toString() 7 | } 8 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/about/AppAbout.kt: -------------------------------------------------------------------------------- 1 | package domain.about 2 | 3 | data class AppAbout( 4 | val appName: String = "", 5 | val appVersion: String = "", 6 | val tagline: String = "" 7 | ) 8 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/appInfo/AppInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.appInfo 2 | 3 | import work.racka.reluct.common.model.domain.core.Icon 4 | 5 | data class AppInfo( 6 | val packageName: String, 7 | val appName: String, 8 | val appIcon: Icon, 9 | ) { 10 | override fun equals(other: Any?): Boolean { 11 | return other?.let { item -> 12 | item is AppInfo && item.appName == this.appName && item.packageName == this.packageName 13 | } ?: false 14 | } 15 | 16 | /** 17 | * This item's hashcode will likely not be the same since the app icon is generated 18 | * in a way that invalidates the equality. Use something else to check if they are the same 19 | */ 20 | override fun hashCode(): Int { 21 | return packageName.hashCode() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/authentication/AuthResults.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.authentication 2 | 3 | enum class EmailResult { 4 | VALID, BLANK, INVALID; 5 | } 6 | 7 | enum class PasswordResult { 8 | VALID, DIGITS_LETTERS_ABSENT, INCORRECT_LENGTH 9 | } 10 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/authentication/EmailUserLogin.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.authentication 2 | 3 | data class EmailUserLogin( 4 | val email: String, 5 | val password: String 6 | ) 7 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/authentication/RegisterUser.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.authentication 2 | 3 | data class RegisterUser( 4 | val displayName: String, 5 | val profilePicUrl: String?, 6 | val email: String, 7 | val password: String, 8 | val repeatPassword: String 9 | ) 10 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/authentication/User.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.authentication 2 | 3 | data class User( 4 | val id: String, 5 | val displayName: String, 6 | val profilePicUrl: String?, 7 | val email: String, 8 | val isEmailVerified: Boolean 9 | ) 10 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/core/Icon.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.core 2 | 3 | expect class Icon 4 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/goals/Goal.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.goals 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import work.racka.reluct.common.model.domain.appInfo.AppInfo 5 | 6 | data class Goal( 7 | val id: String, 8 | val name: String, 9 | val description: String, 10 | val isActive: Boolean, 11 | val relatedApps: ImmutableList, 12 | val targetValue: Long, 13 | val currentValue: Long, 14 | val goalDuration: GoalDuration, 15 | val goalType: GoalType 16 | ) 17 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/goals/GoalDuration.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.goals 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import work.racka.reluct.common.model.util.time.Week 5 | 6 | data class GoalDuration( 7 | val goalInterval: GoalInterval, 8 | val timeRangeInMillis: LongRange?, 9 | val formattedTimeRange: ClosedRange?, 10 | val selectedDaysOfWeek: ImmutableList 11 | ) 12 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/goals/GoalInterval.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.goals 2 | 3 | enum class GoalInterval { 4 | Daily, Weekly, Custom; 5 | } 6 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/goals/GoalType.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.goals 2 | 3 | enum class GoalType { 4 | TasksGoal, AppScreenTimeGoal, DeviceScreenTimeGoal, NumeralGoal; 5 | } 6 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/limits/AppLimits.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.limits 2 | 3 | import work.racka.reluct.common.model.domain.appInfo.AppInfo 4 | 5 | data class AppLimits( 6 | val appInfo: AppInfo, 7 | val timeLimit: Long, 8 | val isADistractingAp: Boolean, 9 | val isPaused: Boolean, 10 | val overridden: Boolean 11 | ) 12 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/limits/AppTimeLimit.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.limits 2 | 3 | import work.racka.reluct.common.model.domain.appInfo.AppInfo 4 | 5 | data class AppTimeLimit( 6 | val appInfo: AppInfo, 7 | val timeInMillis: Long, 8 | val hours: Int, 9 | val minutes: Int, 10 | val formattedTime: String 11 | ) 12 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/tasks/DailyTasksStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.tasks 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.collections.immutable.persistentListOf 5 | 6 | data class DailyTasksStats( 7 | val dateFormatted: String = "...", 8 | val completedTasks: ImmutableList = persistentListOf(), 9 | val pendingTasks: ImmutableList = persistentListOf(), 10 | ) { 11 | val completedTasksCount 12 | get() = completedTasks.size 13 | val pendingTasksCount 14 | get() = pendingTasks.size 15 | } 16 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/tasks/EditTask.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.tasks 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.collections.immutable.persistentListOf 5 | 6 | data class EditTask( 7 | val id: String, 8 | val title: String, 9 | val description: String?, 10 | val done: Boolean, 11 | val overdue: Boolean, 12 | val taskLabels: ImmutableList = persistentListOf(), 13 | val dueDateLocalDateTime: String, 14 | val completedLocalDateTime: String?, 15 | val reminderLocalDateTime: String?, 16 | val timeZoneId: String, 17 | ) 18 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/tasks/Task.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.tasks 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.collections.immutable.persistentListOf 5 | 6 | data class Task( 7 | val id: String, 8 | val title: String, 9 | val description: String, 10 | val done: Boolean, 11 | val overdue: Boolean, 12 | val taskLabels: ImmutableList = persistentListOf(), 13 | val dueDate: String, 14 | val dueTime: String, 15 | val timeLeftLabel: String, 16 | val reminderFormatted: String, 17 | val reminderDateAndTime: String? = null, 18 | val completedDateAndTime: String, 19 | ) 20 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/tasks/TaskLabel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.tasks 2 | 3 | data class TaskLabel( 4 | val id: String, 5 | val name: String, 6 | val description: String, 7 | val colorHexString: String 8 | ) 9 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/usagestats/AppUsageInfo.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.usagestats 2 | 3 | import work.racka.reluct.common.model.domain.core.Icon 4 | 5 | data class AppUsageInfo( 6 | val packageName: String, 7 | val appName: String, 8 | val appIcon: Icon, 9 | val timeInForeground: Long = 0, 10 | val formattedTimeInForeground: String = "", 11 | val appLaunchCount: Int = 0, 12 | ) 13 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/usagestats/AppUsageStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.usagestats 2 | 3 | data class AppUsageStats( 4 | val appUsageInfo: AppUsageInfo, 5 | val dateFormatted: String = "...", 6 | val dayIsoNumber: Int = 0 7 | ) 8 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/domain/usagestats/UsageStats.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.usagestats 2 | 3 | import kotlinx.collections.immutable.ImmutableList 4 | import kotlinx.collections.immutable.persistentListOf 5 | 6 | data class UsageStats( 7 | val appsUsageList: ImmutableList = persistentListOf(), 8 | val dateFormatted: String = "...", 9 | val totalScreenTime: Long = 0L, 10 | val formattedTotalScreenTime: String = "", 11 | val unlockCount: Long = 0L 12 | ) 13 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/enums/billing/ProductsOffered.kt: -------------------------------------------------------------------------------- 1 | package enums.billing 2 | 3 | enum class ProductsOffered( 4 | val skuType: Sku, 5 | val id: String 6 | ) { 7 | Premium( 8 | skuType = Sku.Subscription, 9 | id = "premium_subscription" 10 | ), 11 | } 12 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/enums/billing/Sku.kt: -------------------------------------------------------------------------------- 1 | package enums.billing 2 | 3 | enum class Sku( 4 | val type: String 5 | ) { 6 | Subscription( 7 | type = "subs" 8 | ), 9 | InAppPurchase( 10 | type = "inapp" 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/states/about/AboutSideEffect.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.states.about 2 | 3 | sealed class AboutSideEffect { 4 | data class UpdateFound( 5 | val toastMessage: String 6 | ) : AboutSideEffect() 7 | 8 | data class UpdateNotFound( 9 | val toastMessage: String 10 | ) : AboutSideEffect() 11 | 12 | object Update : AboutSideEffect() 13 | 14 | object NoSideEffect : AboutSideEffect() 15 | } 16 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/states/about/AboutState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.states.about 2 | 3 | import domain.about.AppAbout 4 | 5 | sealed class AboutState { 6 | data class State( 7 | val appAbout: AppAbout = AppAbout(), 8 | val hasUpdates: Boolean = false 9 | ) : AboutState() 10 | 11 | companion object { 12 | val EmptyState = State() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/states/tasks/TasksEvents.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.states.tasks 2 | 3 | sealed class TasksEvents { 4 | object Nothing : TasksEvents() 5 | data class ShowMessageDone(val isDone: Boolean, val msg: String) : TasksEvents() 6 | data class ShowMessage(val msg: String) : TasksEvents() 7 | data class DisplayErrorMsg( 8 | val msg: String, 9 | ) : TasksEvents() 10 | 11 | sealed class Navigation : TasksEvents() { 12 | data class NavigateToTaskDetails( 13 | val taskId: String, 14 | ) : Navigation() 15 | 16 | data class NavigateToEdit( 17 | val taskId: String, 18 | ) : Navigation() 19 | 20 | object GoBack : Navigation() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/util/DataMappers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.util 2 | 3 | object DataMappers { 4 | // Converting data from API to a domain model that will be read by the UI 5 | } 6 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/util/Resource.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.util 2 | 3 | sealed class Resource { 4 | class Success(val data: T) : Resource() 5 | 6 | class Error(val message: String, val data: T? = null) : Resource() 7 | 8 | class Loading(val data: T? = null) : Resource() 9 | } 10 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/util/UUIDGen.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.util 2 | 3 | expect object UUIDGen { 4 | fun getString(): String 5 | } 6 | -------------------------------------------------------------------------------- /common/model/src/commonMain/kotlin/work/racka/reluct/common/model/util/time/TimePeriod.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.util.time 2 | 3 | internal enum class TimePeriod { 4 | MINUTE, 5 | HOUR, 6 | DAY, 7 | MONTH, 8 | YEAR 9 | } 10 | -------------------------------------------------------------------------------- /common/model/src/desktopMain/kotlin/work/racka/reluct/common/model/domain/core/Icon.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.domain.core 2 | 3 | actual class Icon( 4 | val icon: ByteArray 5 | ) 6 | -------------------------------------------------------------------------------- /common/model/src/desktopMain/kotlin/work/racka/reluct/common/model/util/UUIDGen.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.model.util 2 | 3 | import java.util.* 4 | 5 | actual object UUIDGen { 6 | actual fun getString(): String = UUID.randomUUID().toString() 7 | } 8 | -------------------------------------------------------------------------------- /common/mvvm-core/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /common/mvvm-core/src/androidMain/kotlin/work/racka/common/mvvm/koin/vm/KoinCommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.koin.vm 2 | 3 | import org.koin.androidx.viewmodel.dsl.viewModel 4 | import org.koin.core.definition.Definition 5 | import org.koin.core.instance.InstanceFactory 6 | import org.koin.core.qualifier.Qualifier 7 | import work.racka.common.mvvm.viewmodel.CommonViewModel 8 | 9 | actual inline fun org.koin.core.module.Module.commonViewModel( 10 | qualifier: Qualifier?, 11 | noinline definition: Definition 12 | ): Pair> { 13 | return viewModel(qualifier = qualifier, definition = definition) 14 | } 15 | -------------------------------------------------------------------------------- /common/mvvm-core/src/androidMain/kotlin/work/racka/common/mvvm/viewmodel/CommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.viewmodel 2 | 3 | import androidx.lifecycle.ViewModel 4 | import androidx.lifecycle.viewModelScope 5 | import kotlinx.coroutines.CoroutineScope 6 | import java.io.Closeable 7 | 8 | actual abstract class CommonViewModel actual constructor() : ViewModel() { 9 | actual val vmScope: CoroutineScope = viewModelScope 10 | 11 | actual open fun destroy() { 12 | if (vmScope is Closeable) { 13 | (vmScope as Closeable).close() 14 | } 15 | } 16 | 17 | override fun onCleared() { 18 | super.onCleared() 19 | destroy() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/mvvm-core/src/commonMain/kotlin/work/racka/common/mvvm/koin/vm/KoinCommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.koin.vm 2 | 3 | import org.koin.core.definition.Definition 4 | import org.koin.core.instance.InstanceFactory 5 | import org.koin.core.qualifier.Qualifier 6 | import work.racka.common.mvvm.viewmodel.CommonViewModel 7 | 8 | expect inline fun org.koin.core.module.Module.commonViewModel( 9 | qualifier: Qualifier? = null, 10 | noinline definition: Definition 11 | ): Pair> 12 | -------------------------------------------------------------------------------- /common/mvvm-core/src/commonMain/kotlin/work/racka/common/mvvm/viewmodel/CommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.viewmodel 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | 5 | @Suppress("UnnecessaryAbstractClass") 6 | expect abstract class CommonViewModel() { 7 | val vmScope: CoroutineScope 8 | open fun destroy() 9 | } 10 | -------------------------------------------------------------------------------- /common/mvvm-core/src/desktopMain/kotlin/work/racka/common/mvvm/koin/vm/KoinCommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.koin.vm 2 | 3 | import org.koin.core.definition.Definition 4 | import org.koin.core.instance.InstanceFactory 5 | import org.koin.core.qualifier.Qualifier 6 | import work.racka.common.mvvm.viewmodel.CommonViewModel 7 | 8 | actual inline fun org.koin.core.module.Module.commonViewModel( 9 | qualifier: Qualifier?, 10 | noinline definition: Definition 11 | ): Pair> { 12 | return factory(qualifier = qualifier, definition = definition) 13 | } 14 | -------------------------------------------------------------------------------- /common/mvvm-core/src/desktopMain/kotlin/work/racka/common/mvvm/viewmodel/CommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.viewmodel 2 | 3 | import kotlinx.coroutines.* 4 | 5 | @Suppress("UnnecessaryAbstractClass") 6 | actual abstract class CommonViewModel actual constructor() { 7 | actual val vmScope: CoroutineScope = 8 | CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) 9 | 10 | actual open fun destroy() { 11 | vmScope.coroutineContext.cancel() 12 | vmScope.cancel() 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/mvvm-core/src/jsMain/kotlin/work/racka/common/mvvm/koin/vm/KoinCommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.koin.vm 2 | 3 | import org.koin.core.definition.Definition 4 | import org.koin.core.instance.InstanceFactory 5 | import org.koin.core.qualifier.Qualifier 6 | import work.racka.common.mvvm.viewmodel.CommonViewModel 7 | 8 | actual inline fun org.koin.core.module.Module.commonViewModel( 9 | qualifier: Qualifier?, 10 | noinline definition: Definition 11 | ): Pair> { 12 | return factory(qualifier = qualifier, definition = definition) 13 | } 14 | -------------------------------------------------------------------------------- /common/mvvm-core/src/jsMain/kotlin/work/racka/common/mvvm/viewmodel/CommonViewModel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.common.mvvm.viewmodel 2 | 3 | import kotlinx.coroutines.CoroutineScope 4 | import kotlinx.coroutines.Dispatchers 5 | import kotlinx.coroutines.SupervisorJob 6 | import kotlinx.coroutines.cancel 7 | 8 | @Suppress("UnnecessaryAbstractClass") 9 | actual abstract class CommonViewModel actual constructor() { 10 | actual val vmScope: CoroutineScope = 11 | CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) 12 | 13 | actual open fun destroy() { 14 | vmScope.cancel() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /common/network/src/commonMain/kotlin/work/racka/reluct/common/network/di/Network.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.di 2 | 3 | import org.koin.core.KoinApplication 4 | import org.koin.dsl.module 5 | 6 | object Network { 7 | fun KoinApplication.install() = apply { 8 | modules(commonModule(), Platform.module()) 9 | } 10 | 11 | private fun commonModule() = module { } 12 | } 13 | -------------------------------------------------------------------------------- /common/network/src/commonMain/kotlin/work/racka/reluct/common/network/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | expect object Platform { 6 | fun module(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/network/src/commonMain/kotlin/work/racka/reluct/common/network/sync/DbNetworkSync.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.sync 2 | 3 | interface DbNetworkSync { 4 | // Tasks 5 | fun syncTasksData(userId: String) 6 | fun stopSyncTasksData() 7 | } 8 | -------------------------------------------------------------------------------- /common/network/src/commonMain/kotlin/work/racka/reluct/common/network/sync/tasks/TasksUpload.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.sync.tasks 2 | 3 | import work.racka.reluct.common.database.models.TaskDbObject 4 | import work.racka.reluct.common.database.models.TaskLabelDbObject 5 | 6 | interface TasksUpload { 7 | suspend fun uploadTasks(userId: String, tasks: List): Result 8 | suspend fun uploadTask(userId: String, task: TaskDbObject): Result 9 | suspend fun deleteTask(userId: String, taskId: String): Result 10 | 11 | // Labels 12 | suspend fun uploadLabels(userId: String, labels: List): Result 13 | suspend fun uploadLabel(userId: String, label: TaskLabelDbObject): Result 14 | suspend fun deleteLabel(userId: String, labelId: String): Result 15 | } 16 | -------------------------------------------------------------------------------- /common/network/src/commonMain/kotlin/work/racka/reluct/common/network/util/Constants.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.util 2 | 3 | internal object Constants { 4 | const val FIREBASE_DEFAULT_DB_URL = 5 | "https://reluct-app-default-rtdb.asia-southeast1.firebasedatabase.app/" 6 | const val FB_TASKS = "tasks" 7 | const val FB_TASKS_LABELS = "tasks_labels" 8 | } 9 | -------------------------------------------------------------------------------- /common/network/src/desktopMain/kotlin/work/racka/reluct/common/network/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.di 2 | 3 | import org.koin.core.module.Module 4 | import org.koin.dsl.module 5 | import work.racka.reluct.common.network.sync.DbNetworkSync 6 | import work.racka.reluct.common.network.sync.DesktopNetworkSync 7 | import work.racka.reluct.common.network.sync.tasks.DesktopTasksUpload 8 | import work.racka.reluct.common.network.sync.tasks.TasksUpload 9 | 10 | actual object Platform { 11 | actual fun module(): Module = module { 12 | single { 13 | DesktopNetworkSync() 14 | } 15 | 16 | factory { DesktopTasksUpload() } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/network/src/desktopMain/kotlin/work/racka/reluct/common/network/sync/DesktopNetworkSync.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.network.sync 2 | 3 | internal class DesktopNetworkSync : DbNetworkSync { 4 | override fun syncTasksData(userId: String) { 5 | println("Sync Tasks for user id: $userId") 6 | } 7 | 8 | override fun stopSyncTasksData() { 9 | println("Stop Syncing Tasks!") 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /common/persistence/database/src/androidAndroidTest/kotlin/work/racka/reluct/common/database/di/getDatabaseWrapper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver 4 | import work.racka.reluct.common.database.ReluctDatabase 5 | import work.racka.reluct.common.database.adapters.GoalsTableAdapter 6 | import work.racka.reluct.common.database.adapters.TasksTableAdapter 7 | import work.racka.reluct.common.database.dao.DatabaseWrapper 8 | 9 | internal actual fun getDatabaseWrapper(): DatabaseWrapper { 10 | val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) 11 | .also { ReluctDatabase.Schema.create(it) } 12 | return DatabaseWrapper( 13 | ReluctDatabase( 14 | driver, 15 | GoalsTableAdapter = GoalsTableAdapter, 16 | TasksTableAdapter = TasksTableAdapter 17 | ) 18 | ) 19 | } -------------------------------------------------------------------------------- /common/persistence/database/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/persistence/database/src/androidMain/kotlin/work/racka/reluct/common/database/di/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual object CoroutineDispatchers { 7 | actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO 8 | } 9 | -------------------------------------------------------------------------------- /common/persistence/database/src/androidTest/kotlin/work/racka/reluct/common/database/di/GetDatabaseWrapper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver 4 | import work.racka.reluct.common.database.ReluctDatabase 5 | import work.racka.reluct.common.database.adapters.GoalsTableAdapter 6 | import work.racka.reluct.common.database.adapters.TasksTableAdapter 7 | import work.racka.reluct.common.database.dao.DatabaseWrapper 8 | 9 | internal actual fun getDatabaseWrapper(): DatabaseWrapper { 10 | val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) 11 | .also { ReluctDatabase.Schema.create(it) } 12 | return DatabaseWrapper( 13 | ReluctDatabase( 14 | driver, 15 | GoalsTableAdapter = GoalsTableAdapter, 16 | TasksTableAdapter = TasksTableAdapter 17 | ) 18 | ) 19 | } -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/adapters/GoalsTableAdapter.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.adapters 2 | 3 | import com.squareup.sqldelight.EnumColumnAdapter 4 | import work.racka.reluct.common.database.tables.GoalsTable 5 | 6 | internal val GoalsTableAdapter = GoalsTable.Adapter( 7 | relatedAppsAdapter = listOfStringAdapter, 8 | goalIntervalAdapter = EnumColumnAdapter(), 9 | timeIntervalAdapter = longRangeAdapter, 10 | daysOfWeekSelectedAdapter = listOfWeekAdapter, 11 | goalTypeAdapter = EnumColumnAdapter() 12 | ) 13 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/adapters/TasksTableAdapter.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.adapters 2 | 3 | import work.racka.reluct.common.database.tables.TasksTable 4 | 5 | internal val TasksTableAdapter = TasksTable.Adapter( 6 | taskLabelsIdAdapter = listOfStringAdapter 7 | ) 8 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/dao/DatabaseWrapper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.dao 2 | 3 | import work.racka.reluct.common.database.ReluctDatabase 4 | 5 | internal class DatabaseWrapper(val instance: ReluctDatabase?) 6 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/di/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | 5 | expect object CoroutineDispatchers { 6 | val backgroundDispatcher: CoroutineDispatcher 7 | } 8 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun platformDatabaseModule(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/models/GoalDbObject.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.models 2 | 3 | import work.racka.reluct.common.model.domain.goals.GoalInterval 4 | import work.racka.reluct.common.model.domain.goals.GoalType 5 | import work.racka.reluct.common.model.util.time.Week 6 | 7 | typealias PackageName = String 8 | 9 | data class GoalDbObject( 10 | val id: String, 11 | val name: String, 12 | val description: String, 13 | val isActive: Boolean, 14 | val relatedApps: List, 15 | val targetValue: Long, 16 | val currentValue: Long, 17 | val goalInterval: GoalInterval, 18 | val timeInterval: LongRange?, 19 | val daysOfWeekSelected: List, 20 | val goalType: GoalType 21 | ) 22 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/models/LimitsDbObject.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.models 2 | 3 | data class LimitsDbObject( 4 | val packageName: String, 5 | val timeLimit: Long, 6 | val isADistractingAp: Boolean, 7 | val isPaused: Boolean, 8 | val overridden: Boolean 9 | ) 10 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/models/TaskDbObject.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.models 2 | 3 | /** 4 | * We don't store time as Instant to avoid changes in TimeZone rules 5 | * It's best to store time as LocalDateTime then convert it to the correct 6 | * TimeZone if it changes later on. 7 | */ 8 | data class TaskDbObject( 9 | val id: String, 10 | val title: String, 11 | val description: String?, 12 | val done: Boolean, 13 | val overdue: Boolean, 14 | val taskLabels: List = listOf(), 15 | val dueDateLocalDateTime: String, 16 | val completedLocalDateTime: String?, 17 | val reminderLocalDateTime: String?, 18 | val timeZoneId: String, 19 | ) 20 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/models/TaskLabelDbObject.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.models 2 | 3 | data class TaskLabelDbObject( 4 | val id: String, 5 | val name: String, 6 | val description: String, 7 | val colorHexString: String 8 | ) 9 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/util/Constants.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.util 2 | 3 | internal object Constants { 4 | const val RELUCT_DATABASE = "reluct_data.db" 5 | const val FIREBASE_DEFAULT_DB_URL = 6 | "https://reluct-app-default-rtdb.asia-southeast1.firebasedatabase.app/" 7 | } 8 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/kotlin/work/racka/reluct/common/database/util/Helpers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.util 2 | 3 | internal object Helpers 4 | -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/sqldelight/work/racka/reluct/common/database/files/1.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/common/persistence/database/src/commonMain/sqldelight/work/racka/reluct/common/database/files/1.db -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/sqldelight/work/racka/reluct/common/database/files/2.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/common/persistence/database/src/commonMain/sqldelight/work/racka/reluct/common/database/files/2.db -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/sqldelight/work/racka/reluct/common/database/migrations/1.sqm: -------------------------------------------------------------------------------- 1 | ALTER TABLE TasksTable 2 | ADD COLUMN taskLabelsId TEXT NOT NULL 3 | DEFAULT ''; 4 | 5 | UPDATE TasksTable 6 | SET taskLabelsId = ''; 7 | 8 | CREATE TABLE IF NOT EXISTS TaskLabelsTable ( 9 | id TEXT NOT NULL PRIMARY KEY, 10 | name TEXT NOT NULL, 11 | description TEXT NOT NULL, 12 | colorHex TEXT NOT NULL 13 | ); -------------------------------------------------------------------------------- /common/persistence/database/src/commonMain/sqldelight/work/racka/reluct/common/database/tables/TaskLabelsTable.sq: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS TaskLabelsTable ( 2 | id TEXT NOT NULL PRIMARY KEY, 3 | name TEXT NOT NULL, 4 | description TEXT NOT NULL, 5 | colorHex TEXT NOT NULL 6 | ); 7 | 8 | insertLabel: 9 | INSERT OR REPLACE INTO TaskLabelsTable( 10 | id, name, description, colorHex 11 | ) VALUES ?; 12 | 13 | getLables: 14 | SELECT * FROM TaskLabelsTable; 15 | 16 | getLabelById: 17 | SELECT * FROM TaskLabelsTable 18 | WHERE id = :id; 19 | 20 | deleteLabel: 21 | DELETE FROM TaskLabelsTable 22 | WHERE id = :id; 23 | 24 | deleteAll: 25 | DELETE FROM TaskLabelsTable; -------------------------------------------------------------------------------- /common/persistence/database/src/commonTest/kotlin/work/racka/reluct/common/database/di/GetDatabaseWrapper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import work.racka.reluct.common.database.dao.DatabaseWrapper 4 | 5 | internal expect fun getDatabaseWrapper(): DatabaseWrapper -------------------------------------------------------------------------------- /common/persistence/database/src/desktopMain/kotlin/work/racka/reluct/common/database/di/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual object CoroutineDispatchers { 7 | actual val backgroundDispatcher: CoroutineDispatcher = Dispatchers.IO 8 | } 9 | -------------------------------------------------------------------------------- /common/persistence/database/src/desktopTest/kotlin/work/racka/reluct/common/database/di/GetDatabaseWrapper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.database.di 2 | 3 | import com.squareup.sqldelight.sqlite.driver.JdbcSqliteDriver 4 | import work.racka.reluct.common.database.ReluctDatabase 5 | import work.racka.reluct.common.database.adapters.GoalsTableAdapter 6 | import work.racka.reluct.common.database.adapters.TasksTableAdapter 7 | import work.racka.reluct.common.database.dao.DatabaseWrapper 8 | 9 | internal actual fun getDatabaseWrapper(): DatabaseWrapper { 10 | val driver = JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) 11 | .also { ReluctDatabase.Schema.create(it) } 12 | return DatabaseWrapper( 13 | ReluctDatabase( 14 | driver, 15 | GoalsTableAdapter = GoalsTableAdapter, 16 | TasksTableAdapter = TasksTableAdapter 17 | ) 18 | ) 19 | } -------------------------------------------------------------------------------- /common/persistence/settings/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /common/persistence/settings/src/androidMain/kotlin/work/racka/reluct/common/settings/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings.di 2 | 3 | import org.koin.dsl.module 4 | 5 | internal actual object Platform { 6 | actual fun platformSettingsModule() = module { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /common/persistence/settings/src/androidMain/kotlin/work/racka/reluct/common/settings/util/Playground.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings.util 2 | 3 | import com.russhwolf.settings.Settings 4 | 5 | object Playground { 6 | val settings = Settings() 7 | val bool = settings.putBoolean("key", false) 8 | } 9 | -------------------------------------------------------------------------------- /common/persistence/settings/src/commonMain/kotlin/work/racka/reluct/common/settings/AutoFocusMode.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings 2 | 3 | import kotlinx.datetime.LocalTime 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class AutoFocusMode( 8 | val enabled: Boolean, 9 | val timeRange: ClosedRange 10 | ) 11 | -------------------------------------------------------------------------------- /common/persistence/settings/src/commonMain/kotlin/work/racka/reluct/common/settings/Keys.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings 2 | 3 | object Keys { 4 | const val THEME_OPTION = "THEME_OPTION" 5 | const val FOCUS_MODE = "focus_mode" 6 | const val DO_NOT_DISTURB = "do_not_disturb" 7 | const val AUTO_FOCUS_MODE = "do_not_disturb" 8 | const val SAVED_VERSION_CODE = "saved_version_code" 9 | const val ON_BOARDING_SHOWN = "on_boarding_shown" 10 | const val APP_BLOCKING = "app_blocking" 11 | const val LOGIN_SKIPPED = "app_blocking" 12 | 13 | object Defaults { 14 | const val THEME = -1 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /common/persistence/settings/src/commonMain/kotlin/work/racka/reluct/common/settings/MultiplatformSettings.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings 2 | 3 | import kotlinx.coroutines.flow.Flow 4 | 5 | interface MultiplatformSettings { 6 | fun saveThemeSettings(value: Int): Boolean 7 | val theme: Flow 8 | fun saveFocusMode(value: Boolean): Boolean 9 | val focusMode: Flow 10 | fun saveDoNotDisturb(value: Boolean): Boolean 11 | val doNoDisturb: Flow 12 | fun saveVersionCode(value: Int): Boolean 13 | val savedVersionCode: Flow 14 | fun saveOnBoardingShown(value: Boolean): Boolean 15 | val onBoardingShown: Flow 16 | fun saveAppBlocking(value: Boolean): Boolean 17 | val appBlockingEnabled: Flow 18 | 19 | fun saveLoginSkipped(value: Boolean): Boolean 20 | val loginSkipped: Flow 21 | } 22 | -------------------------------------------------------------------------------- /common/persistence/settings/src/commonMain/kotlin/work/racka/reluct/common/settings/di/MultiplatformSettings.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings.di 2 | 3 | import com.russhwolf.settings.Settings 4 | import org.koin.core.KoinApplication 5 | import org.koin.dsl.module 6 | import work.racka.reluct.common.settings.MultiplatformSettings 7 | import work.racka.reluct.common.settings.MultiplatformSettingsImpl 8 | 9 | object MultiplatformSettings { 10 | 11 | fun KoinApplication.settingsModules() = 12 | this.apply { 13 | modules( 14 | commonModule(), 15 | Platform.platformSettingsModule() 16 | ) 17 | } 18 | 19 | private fun commonModule() = module { 20 | single { 21 | val settings = Settings() 22 | MultiplatformSettingsImpl(settings) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/persistence/settings/src/commonMain/kotlin/work/racka/reluct/common/settings/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings.di 2 | 3 | import org.koin.core.module.Module 4 | 5 | internal expect object Platform { 6 | fun platformSettingsModule(): Module 7 | } 8 | -------------------------------------------------------------------------------- /common/persistence/settings/src/desktopMain/kotlin/work/racka/reluct/common/settings/di/Platform.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.settings.di 2 | 3 | import org.koin.dsl.module 4 | 5 | internal actual object Platform { 6 | actual fun platformSettingsModule() = module { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /common/system-services/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /common/system-services/src/androidMain/kotlin/work/racka/reluct/common/services/di/PlatformSystemServicesModule.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.di 2 | 3 | import org.koin.android.ext.koin.androidContext 4 | import org.koin.core.module.Module 5 | import org.koin.dsl.module 6 | import work.racka.reluct.common.services.haptics.AndroidHapticFeedback 7 | import work.racka.reluct.common.services.haptics.HapticFeedback 8 | 9 | internal actual fun platformSystemServicesModule(): Module = module { 10 | single { 11 | AndroidHapticFeedback(context = androidContext()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/system-services/src/androidMain/kotlin/work/racka/reluct/common/services/notifications/defaultChannels/AppAlerts.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.notifications.defaultChannels 2 | 3 | import android.content.Context 4 | import androidx.core.app.NotificationManagerCompat 5 | import work.racka.reluct.common.services.R 6 | import work.racka.reluct.common.services.notifications.NotificationChannelInfo 7 | 8 | fun getAppAlertsChannel(context: Context) = NotificationChannelInfo( 9 | name = context.getString(R.string.app_alerts_notif_channel_title), 10 | description = context.getString(R.string.app_alerts_notif_channel_desc), 11 | channelId = "app_alerts_channel", 12 | importance = NotificationManagerCompat.IMPORTANCE_HIGH 13 | ) 14 | -------------------------------------------------------------------------------- /common/system-services/src/androidMain/kotlin/work/racka/reluct/common/services/util/IntentData.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.util 2 | 3 | class IntentData(val action: String, val key: String) 4 | -------------------------------------------------------------------------------- /common/system-services/src/androidMain/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | App Alerts 4 | All App Alerts that need immediate action 5 | -------------------------------------------------------------------------------- /common/system-services/src/commonMain/kotlin/work/racka/reluct/common/services/di/SystemServices.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.di 2 | 3 | import org.koin.core.KoinApplication 4 | import org.koin.core.module.Module 5 | import org.koin.dsl.module 6 | 7 | object SystemServices { 8 | fun KoinApplication.install() = apply { 9 | modules( 10 | commonModule(), 11 | platformSystemServicesModule() 12 | ) 13 | } 14 | 15 | private fun commonModule() = module { } 16 | } 17 | 18 | internal expect fun platformSystemServicesModule(): Module 19 | -------------------------------------------------------------------------------- /common/system-services/src/commonMain/kotlin/work/racka/reluct/common/services/haptics/HapticFeedback.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.haptics 2 | 3 | interface HapticFeedback { 4 | fun tick() 5 | fun click() 6 | fun doubleClick() 7 | fun heavyClick() 8 | fun cascadeFall() 9 | fun spinAndFall() 10 | fun customDuration(durationMillis: Long) 11 | } 12 | -------------------------------------------------------------------------------- /common/system-services/src/commonMain/kotlin/work/racka/reluct/common/services/notifications/NotificationData.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.notifications 2 | 3 | import work.racka.reluct.common.model.domain.core.Icon 4 | 5 | data class NotificationData( 6 | val iconProvider: Icon?, 7 | val title: String, 8 | val content: String, 9 | val notificationId: Int, 10 | val notificationTag: String, 11 | val category: String? = null 12 | ) 13 | -------------------------------------------------------------------------------- /common/system-services/src/desktopMain/kotlin/work/racka/reluct/common/services/di/PlatformSystemServicesModule.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.di 2 | 3 | import org.koin.core.module.Module 4 | import org.koin.dsl.module 5 | import work.racka.reluct.common.services.haptics.DesktopHapticFeedback 6 | import work.racka.reluct.common.services.haptics.HapticFeedback 7 | 8 | internal actual fun platformSystemServicesModule(): Module = module { 9 | single { 10 | DesktopHapticFeedback() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/system-services/src/desktopMain/kotlin/work/racka/reluct/common/services/haptics/DesktopHapticFeedback.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.common.services.haptics 2 | 3 | internal class DesktopHapticFeedback : HapticFeedback { 4 | override fun tick() { /** ACTION **/ } 5 | 6 | override fun click() { /** ACTION **/ } 7 | 8 | override fun doubleClick() { /** ACTION **/ } 9 | 10 | override fun heavyClick() { /** ACTION **/ } 11 | 12 | override fun cascadeFall() { /** ACTION **/ } 13 | 14 | override fun spinAndFall() { /** ACTION **/ } 15 | 16 | override fun customDuration(durationMillis: Long) { /** ACTION **/ } 17 | } 18 | -------------------------------------------------------------------------------- /compose-common/charts/README.md: -------------------------------------------------------------------------------- 1 | 2 | # DETAILS 3 | 4 | This module is modification of the [compose-charts](https://github.com/bytebeats/compose-charts) lib. 5 | 6 | I've added some few tweaks for my use cases and up to date Compose Multiplatform support. -------------------------------------------------------------------------------- /compose-common/charts/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /compose-common/charts/src/androidMain/kotlin/work/racka/reluct/compose/common/charts/common/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.common 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | actual fun Color.toLegacyInt(): Int { 6 | return android.graphics.Color.argb( 7 | (alpha * 255.0f + 0.5f).toInt(), 8 | (red * 255.0f + 0.5f).toInt(), 9 | (green * 255.0f + 0.5f).toInt(), 10 | (blue * 255.0f + 0.5f).toInt() 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /compose-common/charts/src/androidMain/kotlin/work/racka/reluct/compose/common/charts/util/DrawText.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.util 2 | 3 | import androidx.compose.ui.graphics.Canvas 4 | import androidx.compose.ui.graphics.Paint 5 | import androidx.compose.ui.graphics.nativeCanvas 6 | import work.racka.reluct.compose.common.charts.common.toLegacyInt 7 | 8 | internal actual fun Canvas.drawTextHelper( 9 | text: String, 10 | x: Float, 11 | y: Float, 12 | paint: Paint, 13 | textSize: Float 14 | ) { 15 | val newPaint = android.graphics.Paint().apply { 16 | this.textSize = textSize 17 | this.textAlign = android.graphics.Paint.Align.CENTER 18 | this.color = paint.color.toLegacyInt() 19 | } 20 | this.nativeCanvas.drawText(text, x, y, newPaint) 21 | } 22 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/barChart/BarChartOptions.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.barChart 2 | 3 | data class BarChartOptions( 4 | var drawXAxisLine: Boolean = true, 5 | var drawYAxisLine: Boolean = false, 6 | var showXAxisLabels: Boolean = true, 7 | var showYAxisLabels: Boolean = true, 8 | var showIntervalLines: Boolean = true, 9 | var barsSpacingFactor: Float = 0.1f 10 | ) 11 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/barChart/renderer/bar/BarDrawer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.barChart.renderer.bar 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Canvas 5 | import androidx.compose.ui.graphics.Color 6 | import androidx.compose.ui.graphics.drawscope.DrawScope 7 | import work.racka.reluct.compose.common.charts.barChart.BarChartData 8 | 9 | interface BarDrawer { 10 | fun drawBar( 11 | drawScope: DrawScope, 12 | canvas: Canvas, 13 | barArea: Rect, 14 | bar: BarChartData.Bar, 15 | selected: Boolean = false, 16 | selectedBarColor: Color 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/barChart/renderer/label/LabelDrawer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.barChart.renderer.label 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Canvas 5 | import androidx.compose.ui.graphics.drawscope.DrawScope 6 | 7 | interface LabelDrawer { 8 | fun requiredXAxisHeight(drawScope: DrawScope): Float = 0f 9 | fun requiredAboveBarHeight(drawScope: DrawScope): Float = 0f 10 | 11 | fun drawLabel( 12 | drawScope: DrawScope, 13 | canvas: Canvas, 14 | label: String, 15 | barArea: Rect, 16 | xAxisArea: Rect 17 | ) 18 | } 19 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/barChart/renderer/xaxis/XAxisDrawer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.barChart.renderer.xaxis 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Canvas 5 | import androidx.compose.ui.graphics.drawscope.DrawScope 6 | 7 | interface XAxisDrawer { 8 | fun requiredHeight(drawScope: DrawScope): Float 9 | 10 | fun drawAxisLine( 11 | drawScope: DrawScope, 12 | canvas: Canvas, 13 | drawableArea: Rect 14 | ) 15 | 16 | fun drawIntervalLines( 17 | drawScope: DrawScope, 18 | canvas: Canvas, 19 | drawableArea: Rect 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/barChart/renderer/yaxis/YAxisDrawer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.barChart.renderer.yaxis 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Canvas 5 | import androidx.compose.ui.graphics.drawscope.DrawScope 6 | 7 | interface YAxisDrawer { 8 | 9 | fun drawAxisLine( 10 | drawScope: DrawScope, 11 | canvas: Canvas, 12 | drawableArea: Rect 13 | ) 14 | 15 | fun drawAxisLabels( 16 | drawScope: DrawScope, 17 | canvas: Canvas, 18 | drawableArea: Rect, 19 | minValue: Float, 20 | maxValue: Float 21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/common/AxisLine.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.common 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import androidx.compose.ui.graphics.Paint 5 | import androidx.compose.ui.graphics.PaintingStyle 6 | import androidx.compose.ui.unit.Density 7 | import androidx.compose.ui.unit.Dp 8 | import androidx.compose.ui.unit.dp 9 | 10 | data class AxisLine( 11 | val thickness: Dp = 1.5.dp, 12 | val color: Color = Color.Gray 13 | ) { 14 | private val paint = Paint().apply { 15 | this.color = this@AxisLine.color 16 | this.style = PaintingStyle.Stroke 17 | } 18 | 19 | fun paint(density: Density) = paint.apply { 20 | this.strokeWidth = thickness.value * density.density 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/common/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.common 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | expect fun Color.toLegacyInt(): Int 6 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/common/SimpleChartAnimation.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.common 2 | 3 | import androidx.compose.animation.core.TweenSpec 4 | 5 | fun simpleChartAnimation() = TweenSpec(durationMillis = 500) 6 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/pieChart/PieChartUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.pieChart 2 | 3 | internal object PieChartUtils { 4 | fun calculateAngle( 5 | sliceLength: Float, 6 | totalLength: Float, 7 | progress: Float 8 | ): Float { 9 | return 360.0f * (sliceLength * progress) / totalLength 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/pieChart/renderer/slice/SliceDrawer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.pieChart.renderer.slice 2 | 3 | import androidx.compose.ui.geometry.Size 4 | import androidx.compose.ui.graphics.Canvas 5 | import androidx.compose.ui.graphics.drawscope.DrawScope 6 | import work.racka.reluct.compose.common.charts.pieChart.PieChartData 7 | 8 | interface SliceDrawer { 9 | fun drawSlice( 10 | drawScope: DrawScope, 11 | canvas: Canvas, 12 | area: Size, 13 | startAngle: Float, 14 | sweepAngle: Float, 15 | slice: PieChartData.Slice 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/pieChart/renderer/text/TextDrawer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.pieChart.renderer.text 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Canvas 5 | import androidx.compose.ui.graphics.drawscope.DrawScope 6 | 7 | interface TextDrawer { 8 | 9 | fun drawText( 10 | drawScope: DrawScope, 11 | canvas: Canvas, 12 | text: String, 13 | area: Rect 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/util/DrawText.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.util 2 | 3 | import androidx.compose.ui.graphics.Canvas 4 | import androidx.compose.ui.graphics.Paint 5 | 6 | internal expect fun Canvas.drawTextHelper( 7 | text: String, 8 | x: Float, 9 | y: Float, 10 | paint: Paint, 11 | textSize: Float 12 | ) 13 | -------------------------------------------------------------------------------- /compose-common/charts/src/commonMain/kotlin/work/racka/reluct/compose/common/charts/util/TextBounds.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.util 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Paint 5 | 6 | /** 7 | * Computes the correct compose textBounds for desktop and Android with the 8 | * respective APIs 9 | */ 10 | internal expect fun Paint.getTextBounds( 11 | text: String, 12 | start: Int, 13 | end: Int, 14 | bounds: Rect, 15 | textSize: Float 16 | ): Rect 17 | -------------------------------------------------------------------------------- /compose-common/charts/src/desktopMain/kotlin/work/racka/reluct/compose/common/charts/common/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.common 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | actual fun Color.toLegacyInt(): Int { 6 | return org.jetbrains.skia.Color.makeARGB( 7 | (alpha * 255.0f + 0.5f).toInt(), 8 | (red * 255.0f + 0.5f).toInt(), 9 | (green * 255.0f + 0.5f).toInt(), 10 | (blue * 255.0f + 0.5f).toInt() 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /compose-common/charts/src/desktopMain/kotlin/work/racka/reluct/compose/common/charts/util/DrawText.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.charts.util 2 | 3 | import androidx.compose.ui.graphics.Canvas 4 | import androidx.compose.ui.graphics.Paint 5 | import androidx.compose.ui.graphics.nativeCanvas 6 | import org.jetbrains.skia.Font 7 | 8 | internal actual fun Canvas.drawTextHelper( 9 | text: String, 10 | x: Float, 11 | y: Float, 12 | paint: Paint, 13 | textSize: Float 14 | ) { 15 | val skiaFont = Font().apply { 16 | this.size = textSize 17 | } 18 | this.nativeCanvas.drawString(text, x, y, skiaFont, paint.asFrameworkPaint()) 19 | } 20 | -------------------------------------------------------------------------------- /compose-common/components/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /compose-common/components/src/androidMain/kotlin/work/racka/reluct/compose/common/components/resources/AssetResourceExt.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.resources 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.graphics.painter.Painter 5 | import coil.compose.rememberAsyncImagePainter 6 | import dev.icerock.moko.resources.AssetResource 7 | 8 | fun AssetResource.toAndroidAssetUri() = "file:///android_asset/$originalPath" 9 | 10 | @Composable 11 | actual fun painterResource(resource: AssetResource): Painter = 12 | rememberAsyncImagePainter(model = resource.toAndroidAssetUri()) 13 | -------------------------------------------------------------------------------- /compose-common/components/src/androidMain/kotlin/work/racka/reluct/compose/common/components/statsHelpers/StatsDispatcher.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.statsHelpers 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | 6 | actual object StatsDispatcher { 7 | actual val Dispatcher: CoroutineDispatcher = Dispatchers.Main 8 | } 9 | -------------------------------------------------------------------------------- /compose-common/components/src/androidMain/kotlin/work/racka/reluct/compose/common/components/util/Color.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ColorAndroidJvm") 2 | 3 | package work.racka.reluct.compose.common.components.util 4 | 5 | import androidx.compose.ui.graphics.Color 6 | 7 | actual fun Color.toLegacyInt(): Int { 8 | return android.graphics.Color.argb( 9 | (alpha * 255.0f + 0.5f).toInt(), 10 | (red * 255.0f + 0.5f).toInt(), 11 | (green * 255.0f + 0.5f).toInt(), 12 | (blue * 255.0f + 0.5f).toInt() 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /compose-common/components/src/androidMain/kotlin/work/racka/reluct/compose/common/components/util/PlatformPaddings.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.foundation.layout.imePadding 4 | import androidx.compose.foundation.layout.navigationBarsPadding 5 | import androidx.compose.foundation.layout.statusBarsPadding 6 | import androidx.compose.ui.Modifier 7 | 8 | /** 9 | * All Android platform specific paddings can be found here for ease of use in Common code 10 | * These paddings don't do anything on Desktop & Web side. 11 | */ 12 | actual fun Modifier.navigationBarsPadding() = navigationBarsPadding() 13 | actual fun Modifier.statusBarsPadding(): Modifier = statusBarsPadding() 14 | actual fun Modifier.imePadding(): Modifier = imePadding() 15 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/cards/statistics/BarChartDefaults.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.cards.statistics 2 | 3 | import androidx.compose.material3.MaterialTheme 4 | import androidx.compose.runtime.Composable 5 | 6 | object BarChartDefaults { 7 | 8 | val barColor 9 | @Composable get() = MaterialTheme.colorScheme.secondary.copy(alpha = .7f) 10 | } 11 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/cards/statistics/ChartData.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.cards.statistics 2 | 3 | import androidx.compose.runtime.Stable 4 | import kotlinx.collections.immutable.ImmutableList 5 | import kotlinx.collections.immutable.persistentListOf 6 | 7 | /** 8 | * Data for the charts. Should only be used as Compose state 9 | * @param data List that contains the Slices or Bars to be drawn on the chart 10 | * @param isLoading Loading state of the chart. When it is loading, we expect the [data] to empty 11 | */ 12 | @Stable 13 | data class ChartData( 14 | val data: ImmutableList = persistentListOf(), 15 | val isLoading: Boolean = true 16 | ) 17 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/cards/taskEntry/EntryType.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.cards.taskEntry 2 | 3 | enum class EntryType { 4 | PendingTask, 5 | TasksWithOverdue, 6 | CompletedTask, 7 | Statistics; 8 | } 9 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/cards/taskLabelEntry/TaskLabelsEntryMode.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.cards.taskLabelEntry 2 | 3 | enum class TaskLabelsEntryMode { 4 | SelectLabels, ViewLabels; 5 | } 6 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/images/AsyncImage.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.images 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.graphics.painter.Painter 5 | import work.racka.reluct.common.model.domain.core.Icon 6 | 7 | @Composable 8 | expect fun rememberAsyncImage( 9 | url: String, 10 | onStartLoading: () -> Unit = {}, 11 | onFinishLoading: (isSuccess: Boolean) -> Unit = {} 12 | ): Painter 13 | 14 | @Composable 15 | expect fun painterResource(mppIcon: Icon): Painter 16 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/resources/AssetResourceExt.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.resources 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.graphics.painter.Painter 5 | import dev.icerock.moko.resources.AssetResource 6 | 7 | @Composable 8 | expect fun painterResource(resource: AssetResource): Painter 9 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/resources/ComposeExt.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.resources 2 | 3 | import androidx.compose.runtime.Composable 4 | import dev.icerock.moko.resources.PluralsResource 5 | import dev.icerock.moko.resources.StringResource 6 | 7 | @Composable 8 | expect fun stringResource(resource: StringResource): String 9 | 10 | @Composable 11 | expect fun stringResource(resource: StringResource, vararg formatArgs: Any): String 12 | 13 | @Composable 14 | expect fun pluralStringResource(resource: PluralsResource, quantity: Int): String 15 | 16 | @Composable 17 | expect fun pluralStringResource( 18 | resource: PluralsResource, 19 | quantity: Int, 20 | vararg formatArgs: Any 21 | ): String 22 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/statsHelpers/StatsDispatcher.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.statsHelpers 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | 5 | /** 6 | * Dispatcher necessary for loading charts statistics 7 | * This is necessary because it map the dispatcher to Dispatchers.Swing on desktop 8 | * And Dispatcher.IO on Android 9 | * Depending on Dispatchers.IO for this UI related task on Desktop will crash the app with: 10 | * `"AWT-EventQueue-0" java.lang.IllegalStateException: Method should be called from AWT event dispatch thread` 11 | * 12 | * This makes sure the mapping is done on the correct Event dispatcher for Swing on Desktop 13 | */ 14 | expect object StatsDispatcher { 15 | val Dispatcher: CoroutineDispatcher 16 | } 17 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/textfields/texts/HighlightTextProps.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.textfields.texts 2 | 3 | import androidx.compose.runtime.Stable 4 | import androidx.compose.ui.graphics.Color 5 | 6 | @Stable 7 | class HighlightTextProps( 8 | val text: String, 9 | val url: String? = null, 10 | val color: Color 11 | ) 12 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/util/BottomBarVisibilityHandler.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.runtime.State 5 | 6 | /** 7 | * A visibility handler that decides when to hide or show the bottom bar 8 | * This is defined as separate component to defer state reads and avoid recomposition 9 | */ 10 | @Composable 11 | fun BottomBarVisibilityHandler( 12 | scrollContext: State, 13 | barsVisibility: BarsVisibility, 14 | ) { 15 | if (scrollContext.value.isTop) { 16 | barsVisibility.bottomBar.show() 17 | } else { 18 | barsVisibility.bottomBar.hide() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/util/ColorPalette.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import work.racka.reluct.common.model.domain.core.Icon 5 | 6 | expect fun Icon.extractColor(defaultColor: Color = Color.Gray): Color 7 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/util/EditTitles.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.runtime.Stable 4 | 5 | @Stable 6 | data class EditTitles( 7 | val appBarTitle: String, 8 | val dialogTitle: String 9 | ) 10 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/kotlin/work/racka/reluct/compose/common/components/util/PlatformPaddings.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.ui.Modifier 4 | 5 | /** 6 | * All Android platform specific paddings can be found here for ease of use in Common code 7 | * These paddings don't do anything on Desktop & Web side. 8 | * 9 | * For more information on these please visit the Android dev site regarding Insets 10 | */ 11 | 12 | expect fun Modifier.navigationBarsPadding(): Modifier 13 | expect fun Modifier.statusBarsPadding(): Modifier 14 | expect fun Modifier.imePadding(): Modifier 15 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/base/plurals.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %1s Task 5 | %1s Tasks 6 | 7 | -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/error_occurred.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/error_occurred.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/no_data.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/no_data.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/no_permission.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/no_permission.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/no_task_animation.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/no_task_animation.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/pay_success.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/pay_success.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/payment_failed.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/payment_failed.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/search_animation.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/search_animation.json -------------------------------------------------------------------------------- /compose-common/components/src/commonMain/resources/MR/files/task_saved.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/components/src/commonMain/resources/MR/files/task_saved.json -------------------------------------------------------------------------------- /compose-common/components/src/desktopMain/kotlin/work/racka/reluct/compose/common/components/resources/AssetResourceExt.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.resources 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.graphics.painter.Painter 5 | import dev.icerock.moko.resources.AssetResource 6 | 7 | @Composable 8 | actual fun painterResource(resource: AssetResource): Painter = 9 | androidx.compose.ui.res.painterResource(resourcePath = "files/${resource.originalPath}") 10 | -------------------------------------------------------------------------------- /compose-common/components/src/desktopMain/kotlin/work/racka/reluct/compose/common/components/statsHelpers/StatsDispatcher.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.statsHelpers 2 | 3 | import kotlinx.coroutines.CoroutineDispatcher 4 | import kotlinx.coroutines.Dispatchers 5 | import kotlinx.coroutines.swing.Swing 6 | 7 | actual object StatsDispatcher { 8 | actual val Dispatcher: CoroutineDispatcher = Dispatchers.Swing 9 | } 10 | -------------------------------------------------------------------------------- /compose-common/components/src/desktopMain/kotlin/work/racka/reluct/compose/common/components/util/Color.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ColorDesktopJvm") 2 | 3 | package work.racka.reluct.compose.common.components.util 4 | 5 | import androidx.compose.ui.graphics.Color 6 | 7 | actual fun Color.toLegacyInt(): Int { 8 | return org.jetbrains.skia.Color.makeARGB( 9 | (alpha * 255.0f + 0.5f).toInt(), 10 | (red * 255.0f + 0.5f).toInt(), 11 | (green * 255.0f + 0.5f).toInt(), 12 | (blue * 255.0f + 0.5f).toInt() 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /compose-common/components/src/desktopMain/kotlin/work/racka/reluct/compose/common/components/util/ColorPalette.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.ui.graphics.Color 4 | import work.racka.reluct.common.model.domain.core.Icon 5 | 6 | actual fun Icon.extractColor(defaultColor: Color): Color { 7 | return defaultColor 8 | } 9 | -------------------------------------------------------------------------------- /compose-common/components/src/desktopMain/kotlin/work/racka/reluct/compose/common/components/util/PlatformPaddings.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.components.util 2 | 3 | import androidx.compose.ui.Modifier 4 | 5 | /** 6 | * All Android platform specific paddings can be found here for ease of use in Common code 7 | * These paddings don't do anything on Desktop & Web side. 8 | */ 9 | 10 | actual fun Modifier.navigationBarsPadding(): Modifier = this 11 | actual fun Modifier.statusBarsPadding(): Modifier = this 12 | actual fun Modifier.imePadding(): Modifier = this 13 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/androidMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | actual fun Color.toLegacyInt(): Int { 6 | return android.graphics.Color.argb( 7 | (alpha * 255.0f + 0.5f).toInt(), 8 | (red * 255.0f + 0.5f).toInt(), 9 | (green * 255.0f + 0.5f).toInt(), 10 | (blue * 255.0f + 0.5f).toInt() 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/androidMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/DrawText.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.ui.graphics.Canvas 4 | import androidx.compose.ui.graphics.Paint 5 | import androidx.compose.ui.graphics.nativeCanvas 6 | 7 | internal actual fun Canvas.drawTextHelper( 8 | text: String, 9 | x: Float, 10 | y: Float, 11 | paint: Paint, 12 | textSize: Float 13 | ) { 14 | val newPaint = android.graphics.Paint().apply { 15 | this.textSize = textSize 16 | this.textAlign = android.graphics.Paint.Align.CENTER 17 | this.color = paint.color.toLegacyInt() 18 | } 19 | this.nativeCanvas.drawText(text, x, y, newPaint) 20 | } 21 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/androidMain/kotlin/work/racka/reluct/compose/common/date/time/picker/util/Composables.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ComposableJvm") 2 | 3 | package work.racka.reluct.compose.common.date.time.picker.util 4 | 5 | import androidx.compose.runtime.Composable 6 | import androidx.compose.ui.platform.LocalConfiguration 7 | 8 | @Composable 9 | internal actual fun isSmallDevice(): Boolean = LocalConfiguration.current.screenWidthDp <= 360 10 | 11 | @Composable 12 | internal actual fun isLargeDevice(): Boolean = LocalConfiguration.current.screenWidthDp >= 600 13 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/commonMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | expect fun Color.toLegacyInt(): Int 6 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/commonMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/DateTimeDialogButtonText.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.runtime.Stable 4 | 5 | @Stable 6 | data class DateTimeDialogButtonText( 7 | val positiveText: String? = "OK", 8 | val negativeText: String? = "CANCEL" 9 | ) 10 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/commonMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/DrawText.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.ui.graphics.Canvas 4 | import androidx.compose.ui.graphics.Paint 5 | 6 | internal expect fun Canvas.drawTextHelper( 7 | text: String, 8 | x: Float, 9 | y: Float, 10 | paint: Paint, 11 | textSize: Float 12 | ) 13 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/commonMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/TextBounds.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.ui.geometry.Rect 4 | import androidx.compose.ui.graphics.Paint 5 | 6 | /** 7 | * Computes the correct compose textBounds for desktop and Android with the 8 | * respective APIs 9 | */ 10 | internal expect fun Paint.getTextBounds( 11 | text: String, 12 | start: Int, 13 | end: Int, 14 | bounds: Rect, 15 | textSize: Float 16 | ): Rect 17 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/commonMain/kotlin/work/racka/reluct/compose/common/date/time/picker/date/DatePickerState.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.date 2 | 3 | import androidx.compose.runtime.getValue 4 | import androidx.compose.runtime.mutableStateOf 5 | import androidx.compose.runtime.setValue 6 | import kotlinx.datetime.LocalDate 7 | 8 | internal class DatePickerState( 9 | initialDate: LocalDate, 10 | val colors: DatePickerColors, 11 | val yearRange: IntRange, 12 | ) { 13 | var selected by mutableStateOf(initialDate) 14 | var yearPickerShowing by mutableStateOf(false) 15 | 16 | companion object { 17 | val dayHeaders = listOf("S", "M", "T", "W", "T", "F", "S") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/desktopMain/kotlin/work/racka/reluct/compose/common/date/time/picker/core/ColorUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.date.time.picker.core 2 | 3 | import androidx.compose.ui.graphics.Color 4 | 5 | actual fun Color.toLegacyInt(): Int { 6 | return org.jetbrains.skia.Color.makeARGB( 7 | (alpha * 255.0f + 0.5f).toInt(), 8 | (red * 255.0f + 0.5f).toInt(), 9 | (green * 255.0f + 0.5f).toInt(), 10 | (blue * 255.0f + 0.5f).toInt() 11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /compose-common/date-time-picker/src/desktopMain/kotlin/work/racka/reluct/compose/common/date/time/picker/util/Composables.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ComposablesDesktopJvm") 2 | 3 | package work.racka.reluct.compose.common.date.time.picker.util 4 | 5 | import androidx.compose.runtime.Composable 6 | 7 | @Composable 8 | internal actual fun isSmallDevice(): Boolean = false 9 | 10 | @Composable 11 | internal actual fun isLargeDevice(): Boolean = true 12 | -------------------------------------------------------------------------------- /compose-common/pager/README.md: -------------------------------------------------------------------------------- 1 | 2 | # DETAILS 3 | 4 | - `pager` & `pager-indicators` code is a Multiplatform version of [Accompanist Pager](https://github.com/google/accompanist/tree/main/pager/src/main/java/com/google/accompanist/pager) 5 | - `snapper` code is a Multiplatform version of the [Snapper library](https://github.com/chrisbanes/snapper) 6 | 7 | *Note*: `snapper` has been deprecated in favour of new [SnapFlingBehaviour](https://developer.android.com/reference/kotlin/androidx/compose/foundation/gestures/snapping/SnapFlingBehavior) API in Compose 1.3.0 8 | It has to be migrated once `Compose Multiplatform` reaches `1.3.0` -------------------------------------------------------------------------------- /compose-common/pager/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /compose-common/pager/src/commonMain/kotlin/work/racka/reluct/compose/common/pager/snapper/SnapperLog.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * Code from: https://github.com/chrisbanes/snapper 3 | */ 4 | 5 | package work.racka.reluct.compose.common.pager.snapper 6 | 7 | internal object SnapperLog { 8 | const val debug = false 9 | inline fun d(log: () -> String) { 10 | if (debug) { 11 | log() 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /compose-common/theme/src/androidMain/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /compose-common/theme/src/androidMain/kotlin/work/racka/reluct/compose/common/theme/util/FontResources.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme.util 2 | 3 | import android.annotation.SuppressLint 4 | import androidx.compose.runtime.Composable 5 | import androidx.compose.ui.platform.LocalContext 6 | import androidx.compose.ui.text.font.Font 7 | import androidx.compose.ui.text.font.FontStyle 8 | import androidx.compose.ui.text.font.FontWeight 9 | 10 | @SuppressLint("DiscouragedApi") 11 | @Composable 12 | actual fun fontResources( 13 | font: String, 14 | weight: FontWeight, 15 | style: FontStyle 16 | ): Font { 17 | val context = LocalContext.current 18 | val name = font.substringBefore(".") 19 | val fontRes = context.resources.getIdentifier(name, "font", context.packageName) 20 | return Font(fontRes, weight, style) 21 | } 22 | -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/kotlin/work/racka/reluct/compose/common/theme/Dimens.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme 2 | 3 | import androidx.compose.ui.unit.Dp 4 | import androidx.compose.ui.unit.dp 5 | 6 | enum class Dimens(val size: Dp) { 7 | ExtraSmallPadding(4.dp), 8 | SmallPadding(8.dp), 9 | MediumPadding(16.dp), 10 | UpperMediumPadding(20.dp), 11 | LargePadding(32.dp), 12 | ExtraLargePadding(64.dp) 13 | } 14 | -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/kotlin/work/racka/reluct/compose/common/theme/Shape.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme 2 | 3 | import androidx.compose.foundation.shape.RoundedCornerShape 4 | import androidx.compose.material3.Shapes 5 | import androidx.compose.ui.unit.dp 6 | 7 | val Shapes = Shapes( 8 | small = RoundedCornerShape(4.dp), 9 | medium = RoundedCornerShape(4.dp), 10 | large = RoundedCornerShape(20.dp) 11 | ) 12 | 13 | val BottomSheetShape = RoundedCornerShape( 14 | topStart = 20.dp, 15 | topEnd = 20.dp, 16 | bottomStart = 0.dp, 17 | bottomEnd = 0.dp 18 | ) 19 | -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/kotlin/work/racka/reluct/compose/common/theme/util/ColorSchemeUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme.util 2 | 3 | import androidx.compose.material3.ColorScheme 4 | import androidx.compose.runtime.Composable 5 | 6 | internal expect fun canShowDynamic(): Boolean 7 | 8 | @Composable 9 | internal expect fun dynamicLightScheme(): ColorScheme 10 | 11 | @Composable 12 | internal expect fun dynamicDarkScheme(): ColorScheme 13 | -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/kotlin/work/racka/reluct/compose/common/theme/util/FontResources.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme.util 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.text.font.Font 5 | import androidx.compose.ui.text.font.FontStyle 6 | import androidx.compose.ui.text.font.FontWeight 7 | 8 | /** 9 | * Make sure you fonts are inside a folder called "font" 10 | */ 11 | @Composable 12 | expect fun fontResources( 13 | font: String, 14 | weight: FontWeight, 15 | style: FontStyle 16 | ): Font 17 | -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/resources/font/lexenddeca_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/theme/src/commonMain/resources/font/lexenddeca_bold.ttf -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/resources/font/lexenddeca_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/theme/src/commonMain/resources/font/lexenddeca_light.ttf -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/resources/font/lexenddeca_medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/theme/src/commonMain/resources/font/lexenddeca_medium.ttf -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/resources/font/lexenddeca_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/theme/src/commonMain/resources/font/lexenddeca_regular.ttf -------------------------------------------------------------------------------- /compose-common/theme/src/commonMain/resources/font/lexenddeca_thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/compose-common/theme/src/commonMain/resources/font/lexenddeca_thin.ttf -------------------------------------------------------------------------------- /compose-common/theme/src/desktopMain/kotlin/work/racka/reluct/compose/common/theme/util/ColorSchemeUtils.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme.util 2 | 3 | import androidx.compose.material3.ColorScheme 4 | import androidx.compose.material3.darkColorScheme 5 | import androidx.compose.material3.lightColorScheme 6 | import androidx.compose.runtime.Composable 7 | 8 | internal actual fun canShowDynamic(): Boolean = false 9 | 10 | @Composable 11 | internal actual fun dynamicLightScheme(): ColorScheme = lightColorScheme() 12 | 13 | @Composable 14 | internal actual fun dynamicDarkScheme(): ColorScheme = darkColorScheme() 15 | -------------------------------------------------------------------------------- /compose-common/theme/src/desktopMain/kotlin/work/racka/reluct/compose/common/theme/util/FontResources.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.compose.common.theme.util 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.text.font.Font 5 | import androidx.compose.ui.text.font.FontStyle 6 | import androidx.compose.ui.text.font.FontWeight 7 | import androidx.compose.ui.text.platform.Font 8 | 9 | @Composable 10 | actual fun fontResources( 11 | font: String, 12 | weight: FontWeight, 13 | style: FontStyle 14 | ): Font = Font("font/$font", weight, style) 15 | -------------------------------------------------------------------------------- /desktop/app/src/desktopMain/kotlin/work/racka/reluct/ui/navigationComponents/tabs/TabDefaults.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.navigationComponents.tabs 2 | 3 | import work.racka.reluct.common.core.navigation.destination.graphs.GoalsConfig 4 | import work.racka.reluct.common.core.navigation.destination.graphs.TasksConfig 5 | import work.racka.reluct.compose.common.components.SharedRes 6 | 7 | internal val goalsTabs = arrayOf( 8 | Pair(GoalsConfig.Active, SharedRes.strings.goals_active), 9 | Pair(GoalsConfig.Inactive, SharedRes.strings.goals_inactive), 10 | ) 11 | 12 | internal val tasksTabs = arrayOf( 13 | Pair(TasksConfig.Pending, SharedRes.strings.tasks_pending), 14 | Pair(TasksConfig.Completed, SharedRes.strings.tasks_done), 15 | Pair(TasksConfig.Statistics, SharedRes.strings.tasks_stats), 16 | ) 17 | -------------------------------------------------------------------------------- /desktop/app/src/desktopMain/kotlin/work/racka/reluct/ui/screens/ComposeRenderer.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.screens 2 | 3 | import androidx.compose.runtime.Composable 4 | import androidx.compose.ui.Modifier 5 | 6 | interface ComposeRenderer { 7 | @Composable 8 | fun Render(modifier: Modifier) 9 | } 10 | -------------------------------------------------------------------------------- /desktop/app/src/desktopMain/kotlin/work/racka/reluct/ui/screens/tasks/components/ModifyTaskLabel.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.screens.tasks.components 2 | 3 | import work.racka.reluct.common.model.domain.tasks.TaskLabel 4 | 5 | internal sealed class ModifyTaskLabel { 6 | class Delete(val label: TaskLabel) : ModifyTaskLabel() 7 | class SaveLabel(val label: TaskLabel) : ModifyTaskLabel() 8 | } 9 | -------------------------------------------------------------------------------- /desktop/app/src/desktopMain/resources/icons/launcher/linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/desktop/app/src/desktopMain/resources/icons/launcher/linux.png -------------------------------------------------------------------------------- /desktop/app/src/desktopMain/resources/icons/launcher/macos.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/desktop/app/src/desktopMain/resources/icons/launcher/macos.icns -------------------------------------------------------------------------------- /desktop/app/src/desktopMain/resources/icons/launcher/windows.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/desktop/app/src/desktopMain/resources/icons/launcher/windows.ico -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 19 12:50:59 EAT 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/Client.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct 2 | 3 | import browser.document 4 | import dom.html.HTML 5 | import dom.html.createElement 6 | import react.create 7 | import react.dom.client.createRoot 8 | import work.racka.reluct.ui.MaterialApp 9 | 10 | fun main() { 11 | val container = document.createElement(HTML.div) 12 | .also { document.body.appendChild(it) } 13 | createRoot(container).render(MaterialApp.create()) 14 | } 15 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/common/Area.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.common 2 | 3 | import csstype.ident 4 | 5 | object Area { 6 | val Header = ident("header") 7 | val Sidebar = ident("sidebar") 8 | val Content = ident("content") 9 | } 10 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/common/Sizes.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.common 2 | 3 | import csstype.px 4 | 5 | object Sizes { 6 | object Header { 7 | val Height = 64.px 8 | } 9 | 10 | object Sidebar { 11 | val Width = 135.px 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/ShowCasesModule.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components 2 | 3 | import react.FC 4 | import react.PropsWithChildren 5 | import react.createContext 6 | import work.racka.reluct.ui.entities.Showcases 7 | import work.racka.reluct.ui.hooks.useShowcases 8 | 9 | val ShowCasesContext = createContext() 10 | 11 | val ShowcasesModule = FC { props -> 12 | val users = useShowcases() 13 | 14 | ShowCasesContext(users) { 15 | +props.children 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/ThemeModule.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components 2 | 3 | import mui.material.CssBaseline 4 | import mui.material.styles.Theme 5 | import mui.material.styles.ThemeProvider 6 | import react.* 7 | import work.racka.reluct.ui.common.Themes 8 | 9 | typealias ThemeState = StateInstance 10 | 11 | val ThemeContext = createContext() 12 | 13 | val ThemeModule = FC { props -> 14 | val state = useState(Themes.Light) 15 | val (theme) = state 16 | 17 | ThemeContext(state) { 18 | ThemeProvider { 19 | this.theme = theme 20 | 21 | CssBaseline() 22 | +props.children 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Avatar.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Avatar 4 | import mui.material.AvatarGroup 5 | import react.FC 6 | import react.Props 7 | 8 | val AvatarsShowcase = FC { 9 | AvatarGroup { 10 | max = 4 11 | 12 | Avatar { 13 | alt = "Remy Sharp" 14 | src = "avatar.png" 15 | } 16 | Avatar { 17 | alt = "Travis Howard" 18 | +"TH" 19 | } 20 | Avatar { 21 | alt = "Cindy Baker" 22 | } 23 | Avatar { 24 | alt = "Agnes Walker" 25 | +"AW" 26 | } 27 | Avatar { 28 | alt = "Trevor Henderson" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Badges.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.icons.material.Mail 4 | import mui.material.Badge 5 | import mui.material.BadgeColor 6 | import react.FC 7 | import react.Props 8 | import react.ReactNode 9 | 10 | val BadgesShowcase = FC { 11 | Badge { 12 | color = BadgeColor.primary 13 | badgeContent = ReactNode("5") 14 | 15 | Mail() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Buttons.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Button 4 | import mui.material.ButtonVariant.* 5 | import react.FC 6 | import react.Props 7 | 8 | val ButtonsShowcase = FC { 9 | Button { 10 | variant = text 11 | +"Text" 12 | } 13 | Button { 14 | variant = contained 15 | +"Contained" 16 | } 17 | Button { 18 | variant = outlined 19 | +"Outlined" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Checkbox.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Checkbox 4 | import react.FC 5 | import react.Props 6 | 7 | val CheckboxesShowcase = FC { 8 | Checkbox { 9 | defaultChecked = true 10 | } 11 | Checkbox { 12 | } 13 | Checkbox { 14 | disabled = true 15 | } 16 | Checkbox { 17 | disabled = true 18 | checked = true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Chips.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Chip 4 | import mui.material.ChipVariant.outlined 5 | import react.FC 6 | import react.Props 7 | import react.ReactNode 8 | 9 | val ChipsShowcase = FC { 10 | Chip { 11 | label = ReactNode("Chip Filled") 12 | } 13 | Chip { 14 | label = ReactNode("Chip Outlined") 15 | variant = outlined 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Drawers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Button 4 | import mui.material.ButtonVariant.outlined 5 | import mui.material.Drawer 6 | import mui.material.Toolbar 7 | import react.FC 8 | import react.Props 9 | import react.useState 10 | 11 | val DrawersShowcase = FC { 12 | var isOpen by useState(false) 13 | 14 | Button { 15 | variant = outlined 16 | onClick = { isOpen = true } 17 | +"Open drawer" 18 | } 19 | 20 | Drawer { 21 | open = isOpen 22 | 23 | Toolbar() 24 | 25 | Button { 26 | variant = outlined 27 | onClick = { isOpen = false } 28 | +"Close drawer" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/FloatingActionButton.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.icons.material.Add 4 | import mui.material.Fab 5 | import mui.material.FabColor 6 | import react.FC 7 | import react.Props 8 | 9 | val FloatingActionButtonShowcase = FC { 10 | Fab { 11 | color = FabColor.primary 12 | 13 | Add() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/LinearProgress.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.LinearProgress 4 | import mui.material.LinearProgressColor 5 | import mui.material.Stack 6 | import mui.system.responsive 7 | import react.FC 8 | import react.Props 9 | 10 | // TODO: Add other progresses 11 | val ProgressShowcase = FC { 12 | Stack { 13 | spacing = responsive(2) 14 | 15 | LinearProgress { 16 | color = LinearProgressColor.secondary 17 | } 18 | LinearProgress { 19 | color = LinearProgressColor.success 20 | } 21 | LinearProgress { 22 | color = LinearProgressColor.inherit 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Links.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Link 4 | import mui.material.LinkUnderline 5 | import mui.material.Typography 6 | import react.FC 7 | import react.Props 8 | 9 | val LinksShowcase = FC { 10 | Link { 11 | href = "#" 12 | underline = LinkUnderline.none 13 | Typography { +"underline='none'" } 14 | } 15 | Link { 16 | href = "#" 17 | underline = LinkUnderline.hover 18 | Typography { +"underline='hover'" } 19 | } 20 | Link { 21 | href = "#" 22 | underline = LinkUnderline.always 23 | Typography { +"underline='always'" } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Pagination.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Pagination 4 | import mui.material.PaginationColor 5 | import react.FC 6 | import react.Props 7 | 8 | val PaginationShowcase = FC { 9 | Pagination { 10 | count = 10 11 | } 12 | Pagination { 13 | count = 10 14 | color = PaginationColor.primary 15 | } 16 | Pagination { 17 | count = 10 18 | color = PaginationColor.secondary 19 | } 20 | Pagination { 21 | count = 10 22 | disabled = true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Paper.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import csstype.Display 4 | import csstype.FlexWrap.Companion.wrap 5 | import csstype.px 6 | import mui.material.Box 7 | import mui.material.Paper 8 | import mui.material.PaperVariant.outlined 9 | import mui.material.Typography 10 | import mui.system.sx 11 | import react.FC 12 | import react.Props 13 | 14 | val PaperShowcase = FC { 15 | Box { 16 | sx { 17 | display = Display.flex 18 | flexWrap = wrap 19 | width = 128.px 20 | height = 128.px 21 | } 22 | 23 | Paper { 24 | variant = outlined 25 | 26 | Typography { 27 | +"Outlined Paper Component" 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Pickers.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import muix.pickers.AdapterDateFns 4 | import muix.pickers.CalendarPicker 5 | import muix.pickers.LocalizationProvider 6 | import react.FC 7 | import react.Props 8 | 9 | val PickersShowcase = FC { 10 | LocalizationProvider { 11 | dateAdapter = AdapterDateFns 12 | CalendarPicker { 13 | onChange = { _, _ -> } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Skeleton.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Skeleton 4 | import mui.material.SkeletonVariant.* 5 | import react.FC 6 | import react.Props 7 | 8 | val SkeletonShowcase = FC { 9 | Skeleton { 10 | variant = text 11 | width = 210 12 | } 13 | Skeleton { 14 | variant = circular 15 | width = 40 16 | height = 40 17 | } 18 | Skeleton { 19 | variant = rectangular 20 | width = 210 21 | height = 118 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Snackbars.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Snackbar 4 | import mui.material.Typography 5 | import react.FC 6 | import react.Props 7 | import react.ReactNode 8 | 9 | val SnackbarsShowcase = FC { 10 | Typography { 11 | +"Find me in a bottom-left corner" 12 | } 13 | Snackbar { 14 | open = true 15 | autoHideDuration = 6000 16 | message = ReactNode("Note archived") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Switches.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.Switch 4 | import react.FC 5 | import react.Props 6 | import react.dom.html.ReactHTML.div 7 | 8 | val SwitchesShowcase = FC { 9 | div { 10 | Switch { 11 | defaultChecked = true 12 | } 13 | Switch { 14 | } 15 | Switch { 16 | disabled = true 17 | defaultChecked = true 18 | } 19 | Switch { 20 | disabled = true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/components/showcases/Tooltips.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.components.showcases 2 | 3 | import mui.material.IconButton 4 | import mui.material.SpeedDialIcon 5 | import mui.material.Tooltip 6 | import react.FC 7 | import react.Props 8 | import react.ReactNode 9 | 10 | val TooltipsShowcase = FC { 11 | Tooltip { 12 | title = ReactNode("Speed Dial") 13 | 14 | IconButton { 15 | SpeedDialIcon() 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /web/app/src/main/kotlin/work/racka/reluct/ui/entities/Showcase.kt: -------------------------------------------------------------------------------- 1 | package work.racka.reluct.ui.entities 2 | 3 | import react.FC 4 | import react.Props 5 | 6 | data class Showcase( 7 | val key: String, 8 | val name: String, 9 | val component: FC, 10 | ) 11 | 12 | typealias Showcases = Iterable 13 | -------------------------------------------------------------------------------- /web/app/src/main/resources/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/web/app/src/main/resources/avatar.png -------------------------------------------------------------------------------- /web/app/src/main/resources/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ApimorLabs/Reluct/00f474f13246f426e7efa2deeb36320661a49ed2/web/app/src/main/resources/favicon.ico -------------------------------------------------------------------------------- /web/app/src/main/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Reluct 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /web/app/src/main/resources/style.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | *::-webkit-scrollbar { 10 | display: none; 11 | } -------------------------------------------------------------------------------- /webpack.config.d/polyfill.js: -------------------------------------------------------------------------------- 1 | resolve: { 2 | fallback: { 3 | util: require.resolve('util') 4 | } 5 | } --------------------------------------------------------------------------------