diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 5452c723..793f7dad 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -112,7 +112,7 @@ body: description: | A picture or video is worth a thousand words. - If applicable, drag and drop screenshots or a screen recording to help explain your problem. If your file is too big for Github to accept, try to compress it (ZIP file), or feel free to paste a link to an image/video hoster here instead. + If applicable, drag and drop screenshots or a screen recording to help explain your problem. If your file is too big for Github to accept, try to compress it (ZIP file), or feel free to paste a link to an image/video instead. - type: textarea id: additional-information diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index a0ac2ac9..cf46a3b5 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -20,14 +20,12 @@ body: required: true - label: "I have read the FAQs inside the app (Menu -> About -> FAQs) and my problem isn't listed." required: true - - label: "**I have taken the time to fill in all the required details. I understand that the bug report will be dismissed otherwise.**" + - label: "**I have taken the time to fill in all the required details. I understand that the request will be dismissed otherwise.**" required: true - label: "This issue contains only one feature request." required: true - label: "I have read and understood the [contribution guidelines](https://github.com/FossifyOrg/Clock/blob/master/CONTRIBUTING.md)." required: true - - label: "I optionally [donated](https://fossify.org/donate) to support the Fossify mission." - required: false - type: textarea id: feature-description diff --git a/.github/workflows/image-minimizer.js b/.github/workflows/image-minimizer.js index 6ec67b57..ca4ae10e 100644 --- a/.github/workflows/image-minimizer.js +++ b/.github/workflows/image-minimizer.js @@ -18,7 +18,7 @@ module.exports = async ({github, context}) => { initialBody = context.payload.comment.body; } else if (context.eventName == 'issues') { initialBody = context.payload.issue.body; - } else if (context.eventName == 'pull_request') { + } else if (context.eventName == 'pull_request_target') { initialBody = context.payload.pull_request.body; } else { console.log('Aborting: No body found'); @@ -34,7 +34,7 @@ module.exports = async ({github, context}) => { // Regex for finding images (simple variant) ![ALT_TEXT](https://*.githubusercontent.com//.) const REGEX_USER_CONTENT_IMAGE_LOOKUP = /\!\[(.*)\]\((https:\/\/[-a-z0-9]+\.githubusercontent\.com\/\d+\/[-0-9a-f]{32,512}\.(jpg|gif|png))\)/gm; - const REGEX_ASSETS_IMAGE_LOCKUP = /\!\[(.*)\]\((https:\/\/github\.com\/[-\w\d]+\/[-\w\d]+\/assets\/\d+\/[\-0-9a-f]{32,512})\)/gm; + const REGEX_ASSETS_IMAGE_LOCKUP = /\!\[(.*)\]\((https:\/\/github\.com\/user-attachments\/assets\/[\-0-9a-f]{36,})\)/gm; // Check if we found something let foundSimpleImages = REGEX_USER_CONTENT_IMAGE_LOOKUP.test(initialBody) @@ -77,7 +77,7 @@ module.exports = async ({github, context}) => { repo: context.repo.repo, body: newBody }); - } else if (context.eventName == 'pull_request') { + } else if (context.eventName == 'pull_request_target') { console.log('Updating pull request', context.payload.pull_request.number); await github.rest.pulls.update({ pull_number: context.payload.pull_request.number, diff --git a/.github/workflows/image-minimizer.yml b/.github/workflows/image-minimizer.yml index 56c6eb37..5b9e0c03 100644 --- a/.github/workflows/image-minimizer.yml +++ b/.github/workflows/image-minimizer.yml @@ -5,21 +5,19 @@ on: types: [created, edited] issues: types: [opened, edited] - pull_request: + pull_request_target: types: [opened, edited] -permissions: - issues: write - pull-requests: write - jobs: try-minimize: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + token: ${{ secrets.FOSSIFYBOT_TOKEN }} - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: node-version: 16 @@ -27,9 +25,10 @@ jobs: run: npm i probe-image-size@7.2.3 --ignore-scripts - name: Minimize simple images - uses: actions/github-script@v6 + uses: actions/github-script@v7 timeout-minutes: 3 with: + github-token: ${{ secrets.FOSSIFYBOT_TOKEN }} script: | const script = require('.github/workflows/image-minimizer.js'); await script({github, context}); diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml index eef815bd..0eaf9af8 100644 --- a/.github/workflows/no-response.yml +++ b/.github/workflows/no-response.yml @@ -1,25 +1,24 @@ name: no-response -# Both `issue_comment` and `scheduled` event types are required for this Action -# to work properly. on: - issue_comment: - types: [created] schedule: - # Run daily at midnight. - - cron: '0 0 * * *' - -permissions: - issues: write - pull-requests: write + - cron: '0 0 * * *' # Runs daily at midnight + workflow_dispatch: jobs: noResponse: runs-on: ubuntu-latest steps: - - uses: lee-dohm/no-response@v0.5.0 + - uses: actions/stale@v9 with: - token: ${{ github.token }} + repo-token: ${{ secrets.FOSSIFYBOT_TOKEN }} + days-before-stale: -1 # Number of days of inactivity before an issue is closed for lack of response. - daysUntilClose: 30 - responseRequiredLabel: waiting for author + days-before-close: 14 + only-labels: 'waiting for author' + stale-issue-label: 'waiting for author' + stale-pr-label: 'waiting for author' + remove-stale-when-updated: false + ignore-updates: true + close-issue-message: This issue has been automatically closed due to inactivity. We requested additional information but have not received a response from the original author. Without the requested details, we cannot proceed. If you have or find the information needed, please comment so we can reopen the issue. + close-pr-message: This pull request has been automatically closed due to inactivity. We requested additional information but have not received a response from the original author. Without the requested details, we cannot proceed. If you have the needed information or updates, please reopen the PR or comment so we can continue the review. diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 00000000..36adc78e --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,9 @@ +name: PR + +on: + pull_request: + branches: [ master ] + +jobs: + call-pr-workflow: + uses: FossifyOrg/.github/.github/workflows/pr.yml@main diff --git a/.github/workflows/testing-build.yml b/.github/workflows/testing-build.yml new file mode 100644 index 00000000..33379f92 --- /dev/null +++ b/.github/workflows/testing-build.yml @@ -0,0 +1,10 @@ +name: Testing build (on PR) + +on: + pull_request: + branches: [ master ] + types: [ labeled, opened, synchronize, reopened ] + +jobs: + call-testing-build-workflow: + uses: FossifyOrg/.github/.github/workflows/testing-build.yml@main diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 91ec40de..c4e81ea3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Before you report something, read the reporting rules [here](https://github.com/FossifyOrg/General-Discussion#how-do-i-suggest-an-improvement-ask-a-question-or-report-an-issue) please. ### Contributing as a developer -Some instructions about code style and everything that has to be done to increase the change of your code getting accepted can be found at the [General Discussion](https://github.com/FossifyOrg/General-Discussion#contribution-rules-for-developers) section. +Some instructions about code style and everything that has to be done to increase the chance of your code getting accepted can be found at the [General Discussion](https://github.com/FossifyOrg/General-Discussion#contribution-rules-for-developers) section. ### Contributing as a non developer In case you just want to for example improve a translation, you can find the way of doing it [here](https://github.com/FossifyOrg/General-Discussion#how-can-i-suggest-an-edit-to-a-file). diff --git a/README.md b/README.md index 7e39c0f1..d5d91426 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Fossify Clock Logo -Get it on F-Droid Get it on IzzyOnDroid +Get it on Google Play Get it on F-Droid Get it on IzzyOnDroid Introducing Fossify Clock – the ultimate timekeeping companion designed to enhance your daily routines and promote better sleep habits. With a multitude of functions tailored to your needs, Fossify Clock seamlessly integrates into your life, offering unparalleled convenience and versatility. diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f0bcf6df..50d1e5c9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,7 +6,9 @@ import java.io.FileInputStream plugins { alias(libs.plugins.android) alias(libs.plugins.kotlinAndroid) + alias(libs.plugins.kotlinSerialization) alias(libs.plugins.ksp) + alias(libs.plugins.detekt) } val keystorePropertiesFile: File = rootProject.file("keystore.properties") @@ -74,7 +76,8 @@ android { } compileOptions { - val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get()) + val currentJavaVersionFromLibs = + JavaVersion.valueOf(libs.versions.app.build.javaVersion.get()) sourceCompatibility = currentJavaVersionFromLibs targetCompatibility = currentJavaVersionFromLibs } @@ -91,10 +94,16 @@ android { lint { checkReleaseBuilds = false - abortOnError = false + abortOnError = true + warningsAsErrors = true + baseline = file("lint-baseline.xml") } } +detekt { + baseline = file("detekt-baseline.xml") +} + dependencies { implementation(libs.fossify.commons) @@ -107,6 +116,7 @@ dependencies { implementation(libs.numberpicker) implementation(libs.autofittextview) implementation(libs.eventbus) + implementation(libs.kotlinx.serialization.json) implementation(libs.bundles.room) ksp(libs.androidx.room.compiler) diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml new file mode 100644 index 00000000..2c305f32 --- /dev/null +++ b/app/detekt-baseline.xml @@ -0,0 +1,334 @@ + + + + + ComplexCondition:IntentHandlerActivity.kt$IntentHandlerActivity$existingTimer != null && skipUi && (existingTimer.state is TimerState.Idle || (existingTimer.state is TimerState.Finished && !existingTimer.oneShot)) + CyclomaticComplexMethod:IntentHandlerActivity.kt$IntentHandlerActivity$private fun Intent.dismissAlarm() + CyclomaticComplexMethod:IntentHandlerActivity.kt$IntentHandlerActivity$private fun Intent.setNewAlarm() + EmptyCatchBlock:Context.kt${ } + EmptyCatchBlock:ReminderActivity.kt$ReminderActivity${ } + EmptyFunctionBlock:AlarmsAdapter.kt$AlarmsAdapter${} + EmptyFunctionBlock:StopwatchAdapter.kt$StopwatchAdapter${} + EmptyFunctionBlock:TimeZonesAdapter.kt$TimeZonesAdapter${} + EmptyFunctionBlock:TimerAdapter.kt$TimerAdapter${} + EmptyFunctionBlock:WidgetAnalogueConfigureActivity.kt$WidgetAnalogueConfigureActivity.<no name provided>${} + EmptyFunctionBlock:WidgetDigitalConfigureActivity.kt$WidgetDigitalConfigureActivity.<no name provided>${} + LongMethod:Constants.kt$fun getAllTimeZones() + LongMethod:Context.kt$fun Context.getTimerNotification(timer: Timer, pendingIntent: PendingIntent, addDeleteIntent: Boolean): Notification + LongMethod:IntentHandlerActivity.kt$IntentHandlerActivity$private fun Intent.dismissAlarm() + LongMethod:IntentHandlerActivity.kt$IntentHandlerActivity$private fun Intent.setNewAlarm() + LongMethod:ReminderActivity.kt$ReminderActivity$@SuppressLint("ClickableViewAccessibility") private fun setupAlarmButtons() + MagicNumber:AlarmReceiver.kt$AlarmReceiver$1000L + MagicNumber:AlarmsAdapter.kt$AlarmsAdapter$60 + MagicNumber:App.kt$App$1000L + MagicNumber:App.kt$App.<no name provided>$1000 + MagicNumber:ClockFragment.kt$ClockFragment$1000L + MagicNumber:ClockFragment.kt$ClockFragment$24 + MagicNumber:ClockFragment.kt$ClockFragment$3600 + MagicNumber:ClockFragment.kt$ClockFragment$60 + MagicNumber:Config.kt$Config$300 + MagicNumber:Constants.kt$10 + MagicNumber:Constants.kt$1000 + MagicNumber:Constants.kt$11 + MagicNumber:Constants.kt$12 + MagicNumber:Constants.kt$13 + MagicNumber:Constants.kt$14 + MagicNumber:Constants.kt$15 + MagicNumber:Constants.kt$16 + MagicNumber:Constants.kt$17 + MagicNumber:Constants.kt$18 + MagicNumber:Constants.kt$19 + MagicNumber:Constants.kt$20 + MagicNumber:Constants.kt$21 + MagicNumber:Constants.kt$22 + MagicNumber:Constants.kt$23 + MagicNumber:Constants.kt$24 + MagicNumber:Constants.kt$25 + MagicNumber:Constants.kt$26 + MagicNumber:Constants.kt$27 + MagicNumber:Constants.kt$28 + MagicNumber:Constants.kt$29 + MagicNumber:Constants.kt$3 + MagicNumber:Constants.kt$30 + MagicNumber:Constants.kt$31 + MagicNumber:Constants.kt$32 + MagicNumber:Constants.kt$33 + MagicNumber:Constants.kt$34 + MagicNumber:Constants.kt$35 + MagicNumber:Constants.kt$36 + MagicNumber:Constants.kt$37 + MagicNumber:Constants.kt$38 + MagicNumber:Constants.kt$39 + MagicNumber:Constants.kt$4 + MagicNumber:Constants.kt$40 + MagicNumber:Constants.kt$41 + MagicNumber:Constants.kt$42 + MagicNumber:Constants.kt$43 + MagicNumber:Constants.kt$44 + MagicNumber:Constants.kt$45 + MagicNumber:Constants.kt$46 + MagicNumber:Constants.kt$47 + MagicNumber:Constants.kt$48 + MagicNumber:Constants.kt$49 + MagicNumber:Constants.kt$5 + MagicNumber:Constants.kt$50 + MagicNumber:Constants.kt$51 + MagicNumber:Constants.kt$52 + MagicNumber:Constants.kt$53 + MagicNumber:Constants.kt$54 + MagicNumber:Constants.kt$55 + MagicNumber:Constants.kt$56 + MagicNumber:Constants.kt$57 + MagicNumber:Constants.kt$58 + MagicNumber:Constants.kt$59 + MagicNumber:Constants.kt$6 + MagicNumber:Constants.kt$60 + MagicNumber:Constants.kt$61 + MagicNumber:Constants.kt$62 + MagicNumber:Constants.kt$63 + MagicNumber:Constants.kt$64 + MagicNumber:Constants.kt$65 + MagicNumber:Constants.kt$66 + MagicNumber:Constants.kt$67 + MagicNumber:Constants.kt$68 + MagicNumber:Constants.kt$69 + MagicNumber:Constants.kt$7 + MagicNumber:Constants.kt$70 + MagicNumber:Constants.kt$71 + MagicNumber:Constants.kt$72 + MagicNumber:Constants.kt$73 + MagicNumber:Constants.kt$74 + MagicNumber:Constants.kt$75 + MagicNumber:Constants.kt$76 + MagicNumber:Constants.kt$77 + MagicNumber:Constants.kt$78 + MagicNumber:Constants.kt$79 + MagicNumber:Constants.kt$8 + MagicNumber:Constants.kt$80 + MagicNumber:Constants.kt$81 + MagicNumber:Constants.kt$82 + MagicNumber:Constants.kt$83 + MagicNumber:Constants.kt$84 + MagicNumber:Constants.kt$85 + MagicNumber:Constants.kt$86 + MagicNumber:Constants.kt$87 + MagicNumber:Constants.kt$88 + MagicNumber:Constants.kt$89 + MagicNumber:Constants.kt$9 + MagicNumber:Context.kt$0.4f + MagicNumber:Context.kt$1000 + MagicNumber:Context.kt$12 + MagicNumber:Context.kt$2 + MagicNumber:Context.kt$24 + MagicNumber:Context.kt$3 + MagicNumber:Context.kt$3600 + MagicNumber:Context.kt$5 + MagicNumber:Context.kt$500 + MagicNumber:Context.kt$60 + MagicNumber:Context.kt$7 + MagicNumber:DBHelper.kt$DBHelper$420 + MagicNumber:DBHelper.kt$DBHelper$540 + MagicNumber:DismissAlarmReceiver.kt$DismissAlarmReceiver$5 + MagicNumber:DismissAlarmReceiver.kt$DismissAlarmReceiver$7 + MagicNumber:EditAlarmDialog.kt$EditAlarmDialog$3 + MagicNumber:EditAlarmDialog.kt$EditAlarmDialog$4 + MagicNumber:EditAlarmDialog.kt$EditAlarmDialog$5 + MagicNumber:EditAlarmDialog.kt$EditAlarmDialog$6 + MagicNumber:EditAlarmDialog.kt$EditAlarmDialog$60 + MagicNumber:EditTimerDialog.kt$EditTimerDialog$10 + MagicNumber:EditTimerDialog.kt$EditTimerDialog$60 + MagicNumber:IntentHandlerActivity.kt$IntentHandlerActivity$11 + MagicNumber:IntentHandlerActivity.kt$IntentHandlerActivity$12 + MagicNumber:IntentHandlerActivity.kt$IntentHandlerActivity$23 + MagicNumber:IntentHandlerActivity.kt$IntentHandlerActivity$59 + MagicNumber:IntentHandlerActivity.kt$IntentHandlerActivity$60 + MagicNumber:Long.kt$100 + MagicNumber:Long.kt$1000 + MagicNumber:Long.kt$1000F + MagicNumber:MainActivity.kt$MainActivity$3 + MagicNumber:MyTimePickerDialogDialog.kt$MyTimePickerDialogDialog$3600 + MagicNumber:MyTimePickerDialogDialog.kt$MyTimePickerDialogDialog$60 + MagicNumber:ReminderActivity.kt$ReminderActivity$0.1f + MagicNumber:ReminderActivity.kt$ReminderActivity$0.2f + MagicNumber:ReminderActivity.kt$ReminderActivity$1000L + MagicNumber:ReminderActivity.kt$ReminderActivity$2000L + MagicNumber:ReminderActivity.kt$ReminderActivity$500 + MagicNumber:ReminderActivity.kt$ReminderActivity$50f + MagicNumber:ReminderActivity.kt$ReminderActivity$7 + MagicNumber:Stopwatch.kt$Stopwatch.<no name provided>$10 + MagicNumber:StopwatchService.kt$StopwatchService.<no name provided>$500L + MagicNumber:TimeZonesAdapter.kt$TimeZonesAdapter$1000 + MagicNumber:TimerAdapter.kt$TimerAdapter$0.7f + MagicNumber:TimerFragment.kt$TimerFragment$1000 + MagicNumber:ViewPagerAdapter.kt$ViewPagerAdapter$3 + MagicNumber:WidgetAnalogueConfigureActivity.kt$WidgetAnalogueConfigureActivity$100 + MagicNumber:WidgetDigitalConfigureActivity.kt$WidgetDigitalConfigureActivity$100 + MaxLineLength:AlarmReceiver.kt$AlarmReceiver$NotificationChannel(ALARM_NOTIFICATION_CHANNEL_ID, "Alarm", NotificationManager.IMPORTANCE_HIGH) + MaxLineLength:AlarmReceiver.kt$AlarmReceiver$oldNotificationChannelCleanup(notificationManager) + MaxLineLength:AlarmReceiver.kt$AlarmReceiver$val + MaxLineLength:ClockFragment.kt$ClockFragment$binding.clockTime.textSize = resources.getDimension(R.dimen.clock_text_size_smaller) / resources.displayMetrics.density + MaxLineLength:ClockFragment.kt$ClockFragment$val timeZones = requireContext().getAllTimeZonesModified().filter { selectedTimeZoneIDs.contains(it.id) } as ArrayList<MyTimeZone> + MaxLineLength:Config.kt$Config$set(increaseVolumeGradually) = prefs.edit().putBoolean(INCREASE_VOLUME_GRADUALLY, increaseVolumeGradually).apply() + MaxLineLength:Context.kt$. + MaxLineLength:Context.kt$AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, 0, dismissalTriggerTime, getEarlyAlarmDismissalIntent(alarm)) + MaxLineLength:Context.kt$PendingIntent.getActivity(this, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$PendingIntent.getService(this, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$fun Context.getModifiedTimeZoneTitle(id: Int) + MaxLineLength:Context.kt$return PendingIntent.getActivity(this, OPEN_ALARMS_TAB_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getActivity(this, OPEN_STOPWATCH_TAB_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getActivity(this, REMINDER_ACTIVITY_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getActivity(this, timerId, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getBroadcast(this, EARLY_ALARM_DISMISSAL_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getBroadcast(this, alarm.id, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getBroadcast(this, alarmId, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$return PendingIntent.getBroadcast(this, timerId, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:Context.kt$val dayBits = arrayListOf(MONDAY_BIT, TUESDAY_BIT, WEDNESDAY_BIT, THURSDAY_BIT, FRIDAY_BIT, SATURDAY_BIT, SUNDAY_BIT) + MaxLineLength:Context.kt$val fullString = String.format(getString(org.fossify.commons.R.string.time_remaining), formatMinutesToTimeString(totalMinutes)) + MaxLineLength:DBHelper.kt$DBHelper$"$COL_IS_ENABLED INTEGER, $COL_VIBRATE INTEGER, $COL_SOUND_TITLE TEXT, $COL_SOUND_URI TEXT, $COL_LABEL TEXT, $COL_ONE_SHOT INTEGER)" + MaxLineLength:DBHelper.kt$DBHelper$"CREATE TABLE IF NOT EXISTS $ALARMS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_TIME_IN_MINUTES INTEGER, $COL_DAYS INTEGER, " + MaxLineLength:DBHelper.kt$DBHelper$val alarm = Alarm(id, timeInMinutes, days, isEnabled, vibrate, soundTitle, soundUri, label, oneShot) + MaxLineLength:DBHelper.kt$DBHelper$val cols = arrayOf(COL_ID, COL_TIME_IN_MINUTES, COL_DAYS, COL_IS_ENABLED, COL_VIBRATE, COL_SOUND_TITLE, COL_SOUND_URI, COL_LABEL, COL_ONE_SHOT) + MaxLineLength:EditAlarmDialog.kt$EditAlarmDialog$SelectAlarmSoundDialog + MaxLineLength:EditAlarmDialog.kt$EditAlarmDialog$class + MaxLineLength:EditAlarmDialog.kt$EditAlarmDialog$val dayLetters = activity.resources.getStringArray(org.fossify.commons.R.array.week_day_letters).toList() as ArrayList<String> + MaxLineLength:EditTimeZoneDialog.kt$EditTimeZoneDialog$. + MaxLineLength:IntentHandlerActivity.kt$IntentHandlerActivity$&& + MaxLineLength:IntentHandlerActivity.kt$IntentHandlerActivity$alarms = alarms.filter { it.timeInMinutes / 60 == hour || it.timeInMinutes / 60 == hour + 12 } + MaxLineLength:IntentHandlerActivity.kt$IntentHandlerActivity$it.timeInMinutes == timeInMinutes && (it.days.isBitSet(dayBitToLookFor) || it.days == dayToLookFor) + MaxLineLength:Long.kt$val seconds = TimeUnit.MILLISECONDS.toSeconds(this) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(this)) + MaxLineLength:MainActivity.kt$MainActivity$(drawable as LayerDrawable).findDrawableByLayerId(R.id.shortcut_stopwatch_background).applyColorFilter(appIconColor) + MaxLineLength:MainActivity.kt$MainActivity$binding.mainTabsHolder.getTabAt(binding.viewPager.currentItem)?.icon?.applyColorFilter(getProperPrimaryColor()) + MaxLineLength:MainActivity.kt$MainActivity$binding.mainTabsHolder.newTab().setCustomView(org.fossify.commons.R.layout.bottom_tablayout_item) + MaxLineLength:MainActivity.kt$MainActivity$faqItems.add(FAQItem(org.fossify.commons.R.string.faq_2_title_commons, org.fossify.commons.R.string.faq_2_text_commons)) + MaxLineLength:MainActivity.kt$MainActivity$faqItems.add(FAQItem(org.fossify.commons.R.string.faq_6_title_commons, org.fossify.commons.R.string.faq_6_text_commons)) + MaxLineLength:MainActivity.kt$MainActivity$findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(org.fossify.commons.R.bool.hide_google_relations) + MaxLineLength:MainActivity.kt$MainActivity$updateMaterialActivityViews(binding.mainCoordinator, binding.mainHolder, useTransparentNavigation = false, useTopSearchMenu = false) + MaxLineLength:MyAnalogueTimeWidgetProvider.kt$MyAnalogueTimeWidgetProvider$override + MaxLineLength:MyAnalogueTimeWidgetProvider.kt$MyAnalogueTimeWidgetProvider$val pendingIntent = PendingIntent.getActivity(context, OPEN_APP_INTENT_ID, this, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:MyDigitalTimeWidgetProvider.kt$MyDigitalTimeWidgetProvider$override + MaxLineLength:MyDigitalTimeWidgetProvider.kt$MyDigitalTimeWidgetProvider$val pendingIntent = PendingIntent.getActivity(context, OPEN_APP_INTENT_ID, this, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) + MaxLineLength:MyTimePickerDialogDialog.kt$MyTimePickerDialogDialog$class + MaxLineLength:ReminderActivity.kt$ReminderActivity$arrayOf(binding.reminderSnooze, binding.reminderDraggableBackground, binding.reminderDraggable, binding.reminderDismiss) + MaxLineLength:ReminderActivity.kt$ReminderActivity$binding.reminderStop.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, getProperPrimaryColor()) + MaxLineLength:ReminderActivity.kt$ReminderActivity$binding.reminderText.text = if (isAlarmReminder) getFormattedTime(getPassedSeconds(), false, false) else getString(R.string.time_expired) + MaxLineLength:ReminderActivity.kt$ReminderActivity$scheduleVolumeIncrease(MIN_ALARM_VOLUME_FOR_INCREASING_ALARMS.toFloat(), initialAlarmVolume!!.toFloat(), 0) + MaxLineLength:SelectAlarmDialog.kt$SelectAlarmDialog$binding.dialogSelectAlarmRadio.addView(radioButton, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + MaxLineLength:SelectAlarmDialog.kt$SelectAlarmDialog$setColors(activity.getProperTextColor(), activity.getProperPrimaryColor(), activity.getProperBackgroundColor()) + MaxLineLength:SelectTimeZonesAdapter.kt$SelectTimeZonesAdapter$class + MaxLineLength:SettingsActivity.kt$SettingsActivity$binding.settingsUseEnglishHolder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) + MaxLineLength:SettingsActivity.kt$SettingsActivity$updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false) + MaxLineLength:StopwatchAdapter.kt$StopwatchAdapter$class + MaxLineLength:StopwatchFragment.kt$StopwatchFragment$if (state == Stopwatch.State.RUNNING) org.fossify.commons.R.drawable.ic_pause_vector else org.fossify.commons.R.drawable.ic_play_vector + MaxLineLength:StopwatchFragment.kt$StopwatchFragment$stopwatchPlayPause.background = resources.getColoredDrawableWithColor(R.drawable.circle_background_filled, properPrimaryColor) + MaxLineLength:StopwatchFragment.kt$StopwatchFragment$var bitmap = requireContext().resources.getColoredBitmap(R.drawable.ic_sorting_triangle_vector, requireContext().getProperPrimaryColor()) + MaxLineLength:TimeZonesAdapter.kt$TimeZonesAdapter$class + MaxLineLength:TimerAdapter.kt$TimerAdapter$is TimerState.Finished -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis)) + MaxLineLength:TimerAdapter.kt$TimerAdapter$is TimerState.Idle -> EventBus.getDefault().post(TimerEvent.Start(timer.id!!, timer.seconds.secondsToMillis)) + MaxLineLength:TimerAdapter.kt$TimerAdapter$is TimerState.Running -> EventBus.getDefault().post(TimerEvent.Pause(timer.id!!, state.tick)) + MaxLineLength:TimerAdapter.kt$TimerAdapter$val resetPossible = state is TimerState.Running || state is TimerState.Paused || state is TimerState.Finished + MaxLineLength:TimerFragment.kt$TimerFragment$if + MaxLineLength:TimerFragment.kt$TimerFragment$timerAdapter = TimerAdapter(requireActivity() as SimpleActivity, binding.timersList, ::refreshTimers, ::openEditTimer) + MaxLineLength:TimerService.kt$TimerService$else -> resources.getQuantityString(R.plurals.timer_notification_msg, runningTimers.size, runningTimers.size) + MaxLineLength:TimerService.kt$TimerService$firstTimer.label.isNotEmpty() -> getString(R.string.timer_single_notification_label_msg, firstTimer.label) + MaxLineLength:TimerService.kt$TimerService$startForeground(TIMER_RUNNING_NOTIF_ID, notification(formattedDuration, contextText, firstTimer.id!!)) + MaxLineLength:TimerService.kt$TimerService$startForeground(TIMER_RUNNING_NOTIF_ID, notification(getString(R.string.app_name), getString(R.string.timers_notification_msg), INVALID_TIMER_ID)) + MaxLineLength:WidgetAnalogueConfigureActivity.kt$WidgetAnalogueConfigureActivity$if + MaxLineLength:WidgetDigitalConfigureActivity.kt$WidgetDigitalConfigureActivity$if + NestedBlockDepth:AlarmReceiver.kt$AlarmReceiver$override fun onReceive(context: Context, intent: Intent) + NestedBlockDepth:Context.kt$fun Context.scheduleNextAlarm(alarm: Alarm, showToast: Boolean) + NestedBlockDepth:DBHelper.kt$DBHelper$fun getAlarms(): ArrayList<Alarm> + NestedBlockDepth:IntentHandlerActivity.kt$IntentHandlerActivity$private fun Intent.dismissAlarm() + NestedBlockDepth:IntentHandlerActivity.kt$IntentHandlerActivity$private fun Intent.setNewAlarm() + ReturnCount:Context.kt$fun Context.firstDayOrder(bitMask: Int): Int + SwallowedException:Config.kt$Config$e: Exception + SwallowedException:Context.kt$e: Exception + SwallowedException:Converters.kt$Converters$e: Exception + SwallowedException:DBHelper.kt$DBHelper$e: Exception + SwallowedException:IntentHandlerActivity.kt$IntentHandlerActivity$e: Exception + SwallowedException:ReminderActivity.kt$ReminderActivity$e: Exception + TooGenericExceptionCaught:AlarmReceiver.kt$AlarmReceiver$e: Exception + TooGenericExceptionCaught:App.kt$App$e: Exception + TooGenericExceptionCaught:Config.kt$Config$e: Exception + TooGenericExceptionCaught:Context.kt$e: Exception + TooGenericExceptionCaught:Converters.kt$Converters$e: Exception + TooGenericExceptionCaught:DBHelper.kt$DBHelper$e: Exception + TooGenericExceptionCaught:IntentHandlerActivity.kt$IntentHandlerActivity$e: Exception + TooGenericExceptionCaught:ReminderActivity.kt$ReminderActivity$e: Exception + TooGenericExceptionCaught:StopwatchService.kt$e: Exception + TooGenericExceptionCaught:TimerService.kt$TimerService$e: Exception + TooGenericExceptionCaught:TimerService.kt$e: Exception + TooGenericExceptionThrown:ViewPagerAdapter.kt$ViewPagerAdapter$throw RuntimeException("Trying to fetch unknown fragment id $position") + TooManyFunctions:AlarmFragment.kt$AlarmFragment : FragmentToggleAlarmInterface + TooManyFunctions:AlarmsAdapter.kt$AlarmsAdapter : MyRecyclerViewAdapter + TooManyFunctions:Constants.kt$org.fossify.clock.helpers.Constants.kt + TooManyFunctions:Context.kt$org.fossify.clock.extensions.Context.kt + TooManyFunctions:DBHelper.kt$DBHelper : SQLiteOpenHelper + TooManyFunctions:IntentHandlerActivity.kt$IntentHandlerActivity : SimpleActivity + TooManyFunctions:MainActivity.kt$MainActivity : SimpleActivity + TooManyFunctions:ReminderActivity.kt$ReminderActivity : SimpleActivity + TooManyFunctions:SettingsActivity.kt$SettingsActivity : SimpleActivity + TooManyFunctions:StopwatchAdapter.kt$StopwatchAdapter : MyRecyclerViewAdapter + TooManyFunctions:StopwatchFragment.kt$StopwatchFragment : Fragment + TooManyFunctions:TimeZonesAdapter.kt$TimeZonesAdapter : MyRecyclerViewAdapter + TooManyFunctions:TimerAdapter.kt$TimerAdapter : MyRecyclerViewListAdapter + TooManyFunctions:ViewPagerAdapter.kt$ViewPagerAdapter : FragmentStatePagerAdapter + UnusedParameter:AlarmFragment.kt$AlarmFragment$event: AlarmEvent.Refresh + UnusedParameter:MyDigitalTimeWidgetProvider.kt$MyDigitalTimeWidgetProvider$context: Context + UnusedParameter:StopwatchService.kt$StopwatchService$event: StopwatchStopService + UnusedParameter:TimerFragment.kt$TimerFragment$event: TimerEvent.Refresh + UnusedParameter:TimerService.kt$TimerService$event: TimerEvent.Refresh + UnusedParameter:TimerService.kt$TimerService$event: TimerStopService + UnusedPrivateMember:App.kt$App$@OnLifecycleEvent(Lifecycle.Event.ON_START) private fun onAppForegrounded() + UnusedPrivateMember:App.kt$App$@OnLifecycleEvent(Lifecycle.Event.ON_STOP) private fun onAppBackgrounded() + VariableNaming:ClockFragment.kt$ClockFragment$private val ONE_SECOND = 1000L + VariableNaming:DBHelper.kt$DBHelper$private val ALARMS_TABLE_NAME = "contacts" // wrong table name, ignore it + VariableNaming:DBHelper.kt$DBHelper$private val COL_DAYS = "days" + VariableNaming:DBHelper.kt$DBHelper$private val COL_ID = "id" + VariableNaming:DBHelper.kt$DBHelper$private val COL_IS_ENABLED = "is_enabled" + VariableNaming:DBHelper.kt$DBHelper$private val COL_LABEL = "label" + VariableNaming:DBHelper.kt$DBHelper$private val COL_ONE_SHOT = "one_shot" + VariableNaming:DBHelper.kt$DBHelper$private val COL_SOUND_TITLE = "sound_title" + VariableNaming:DBHelper.kt$DBHelper$private val COL_SOUND_URI = "sound_uri" + VariableNaming:DBHelper.kt$DBHelper$private val COL_TIME_IN_MINUTES = "time_in_minutes" + VariableNaming:DBHelper.kt$DBHelper$private val COL_VIBRATE = "vibrate" + VariableNaming:Long.kt$val MSFormat = if (useLongerMSFormat) "%03d" else "%01d" + VariableNaming:TimerFragment.kt$TimerFragment$private val INVALID_POSITION = -1 + WildcardImport:AlarmFragment.kt$import org.fossify.clock.extensions.* + WildcardImport:AlarmFragment.kt$import org.fossify.clock.helpers.* + WildcardImport:AlarmReceiver.kt$import org.fossify.clock.extensions.* + WildcardImport:AlarmsAdapter.kt$import org.fossify.clock.extensions.* + WildcardImport:App.kt$import org.fossify.clock.extensions.* + WildcardImport:ClockFragment.kt$import org.fossify.clock.extensions.* + WildcardImport:Constants.kt$import org.fossify.commons.helpers.* + WildcardImport:Context.kt$import android.app.* + WildcardImport:Context.kt$import org.fossify.clock.helpers.* + WildcardImport:Context.kt$import org.fossify.clock.receivers.* + WildcardImport:Context.kt$import org.fossify.commons.extensions.* + WildcardImport:Context.kt$import org.fossify.commons.helpers.* + WildcardImport:DBHelper.kt$import org.fossify.commons.helpers.* + WildcardImport:DismissAlarmReceiver.kt$import org.fossify.clock.extensions.* + WildcardImport:EditAlarmDialog.kt$import org.fossify.clock.extensions.* + WildcardImport:EditAlarmDialog.kt$import org.fossify.commons.extensions.* + WildcardImport:EditTimerDialog.kt$import org.fossify.clock.extensions.* + WildcardImport:EditTimerDialog.kt$import org.fossify.commons.extensions.* + WildcardImport:IntentHandlerActivity.kt$import org.fossify.clock.extensions.* + WildcardImport:IntentHandlerActivity.kt$import org.fossify.clock.helpers.* + WildcardImport:IntentHandlerActivity.kt$import org.fossify.clock.models.* + WildcardImport:MainActivity.kt$import org.fossify.clock.helpers.* + WildcardImport:MainActivity.kt$import org.fossify.commons.extensions.* + WildcardImport:MainActivity.kt$import org.fossify.commons.helpers.* + WildcardImport:MyDigitalTimeWidgetProvider.kt$import android.graphics.* + WildcardImport:ReminderActivity.kt$import android.os.* + WildcardImport:ReminderActivity.kt$import org.fossify.clock.extensions.* + WildcardImport:ReminderActivity.kt$import org.fossify.commons.extensions.* + WildcardImport:SelectAlarmDialog.kt$import org.fossify.commons.extensions.* + WildcardImport:SettingsActivity.kt$import org.fossify.commons.extensions.* + WildcardImport:SplashActivity.kt$import org.fossify.clock.helpers.* + WildcardImport:StopwatchFragment.kt$import org.fossify.commons.extensions.* + WildcardImport:TimerAdapter.kt$import org.fossify.commons.extensions.* + WildcardImport:TimerDao.kt$import androidx.room.* + WildcardImport:ViewPagerAdapter.kt$import org.fossify.clock.helpers.* + WildcardImport:WidgetAnalogueConfigureActivity.kt$import org.fossify.commons.extensions.* + WildcardImport:WidgetDigitalConfigureActivity.kt$import org.fossify.commons.extensions.* + + diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml new file mode 100644 index 00000000..1dc92ab9 --- /dev/null +++ b/app/lint-baseline.xml @@ -0,0 +1,1811 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/kotlin/org/fossify/clock/activities/MainActivity.kt b/app/src/main/kotlin/org/fossify/clock/activities/MainActivity.kt index 66feee2f..1de09b0f 100644 --- a/app/src/main/kotlin/org/fossify/clock/activities/MainActivity.kt +++ b/app/src/main/kotlin/org/fossify/clock/activities/MainActivity.kt @@ -13,10 +13,7 @@ import org.fossify.clock.BuildConfig import org.fossify.clock.R import org.fossify.clock.adapters.ViewPagerAdapter import org.fossify.clock.databinding.ActivityMainBinding -import org.fossify.clock.extensions.config -import org.fossify.clock.extensions.getEnabledAlarms -import org.fossify.clock.extensions.rescheduleEnabledAlarms -import org.fossify.clock.extensions.updateWidgets +import org.fossify.clock.extensions.* import org.fossify.clock.helpers.* import org.fossify.commons.databinding.BottomTablayoutItemBinding import org.fossify.commons.extensions.* @@ -142,7 +139,7 @@ class MainActivity : SimpleActivity() { private fun refreshMenuItems() { binding.mainToolbar.menu.apply { - findItem(R.id.sort).isVisible = binding.viewPager.currentItem == TAB_ALARM + findItem(R.id.sort).isVisible = binding.viewPager.currentItem == getTabIndex(TAB_ALARM) findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(org.fossify.commons.R.bool.hide_google_relations) } } @@ -150,7 +147,7 @@ class MainActivity : SimpleActivity() { override fun onNewIntent(intent: Intent) { if (intent.extras?.containsKey(OPEN_TAB) == true) { val tabToOpen = intent.getIntExtra(OPEN_TAB, TAB_CLOCK) - binding.viewPager.setCurrentItem(tabToOpen, false) + binding.viewPager.setCurrentItem(getTabIndex(tabToOpen), false) if (tabToOpen == TAB_TIMER) { val timerId = intent.getIntExtra(TIMER_ID, INVALID_TIMER_ID) (binding.viewPager.adapter as ViewPagerAdapter).updateTimerPosition(timerId) @@ -172,8 +169,10 @@ class MainActivity : SimpleActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { super.onActivityResult(requestCode, resultCode, resultData) - if (requestCode == PICK_AUDIO_FILE_INTENT_ID && resultCode == RESULT_OK && resultData != null) { - storeNewAlarmSound(resultData) + when { + requestCode == PICK_AUDIO_FILE_INTENT_ID && resultCode == RESULT_OK && resultData != null -> { + storeNewAlarmSound(resultData) + } } } @@ -181,8 +180,8 @@ class MainActivity : SimpleActivity() { val newAlarmSound = storeNewYourAlarmSound(resultData) when (binding.viewPager.currentItem) { - TAB_ALARM -> getViewPagerAdapter()?.updateAlarmTabAlarmSound(newAlarmSound) - TAB_TIMER -> getViewPagerAdapter()?.updateTimerTabAlarmSound(newAlarmSound) + TAB_ALARM_INDEX -> getViewPagerAdapter()?.updateAlarmTabAlarmSound(newAlarmSound) + TAB_TIMER_INDEX -> getViewPagerAdapter()?.updateTimerTabAlarmSound(newAlarmSound) } } @@ -200,7 +199,7 @@ class MainActivity : SimpleActivity() { refreshMenuItems() } - val tabToOpen = intent.getIntExtra(OPEN_TAB, config.lastUsedViewPagerPage) + val tabToOpen = intent.getIntExtra(OPEN_TAB, config.defaultTab) intent.removeExtra(OPEN_TAB) if (tabToOpen == TAB_TIMER) { val timerId = intent.getIntExtra(TIMER_ID, INVALID_TIMER_ID) @@ -212,7 +211,7 @@ class MainActivity : SimpleActivity() { } binding.viewPager.offscreenPageLimit = TABS_COUNT - 1 - binding.viewPager.currentItem = tabToOpen + binding.viewPager.currentItem = getTabIndex(tabToOpen) } private fun setupTabs() { @@ -308,4 +307,14 @@ class MainActivity : SimpleActivity() { config.isSundayFirst = false } } + + private fun getTabIndex(tabId: Int): Int { + return when (tabId) { + TAB_CLOCK -> TAB_CLOCK_INDEX + TAB_ALARM -> TAB_ALARM_INDEX + TAB_STOPWATCH -> TAB_STOPWATCH_INDEX + TAB_TIMER -> TAB_TIMER_INDEX + else -> config.lastUsedViewPagerPage + } + } } diff --git a/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt b/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt index 1f79ec68..d1e7ab2b 100644 --- a/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt @@ -1,30 +1,95 @@ package org.fossify.clock.activities +import android.content.ActivityNotFoundException import android.content.Intent +import android.net.Uri import android.os.Bundle +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import org.fossify.clock.R import org.fossify.clock.databinding.ActivitySettingsBinding +import org.fossify.clock.dialogs.ExportDataDialog import org.fossify.clock.extensions.config +import org.fossify.clock.extensions.dbHelper +import org.fossify.clock.extensions.timerDb +import org.fossify.clock.helpers.DBHelper import org.fossify.clock.helpers.DEFAULT_MAX_ALARM_REMINDER_SECS import org.fossify.clock.helpers.DEFAULT_MAX_TIMER_REMINDER_SECS +import org.fossify.clock.helpers.EXPORT_BACKUP_MIME_TYPE +import org.fossify.clock.helpers.ExportHelper +import org.fossify.clock.helpers.IMPORT_BACKUP_MIME_TYPES +import org.fossify.clock.helpers.ImportHelper +import org.fossify.clock.helpers.TAB_ALARM +import org.fossify.clock.helpers.TAB_CLOCK +import org.fossify.clock.helpers.TAB_STOPWATCH +import org.fossify.clock.helpers.TAB_TIMER +import org.fossify.clock.helpers.TimerHelper +import org.fossify.clock.models.AlarmTimerBackup import org.fossify.commons.dialogs.RadioGroupDialog -import org.fossify.commons.extensions.* +import org.fossify.commons.extensions.beGone +import org.fossify.commons.extensions.beGoneIf +import org.fossify.commons.extensions.beVisible +import org.fossify.commons.extensions.beVisibleIf +import org.fossify.commons.extensions.formatMinutesToTimeString +import org.fossify.commons.extensions.formatSecondsToTimeString +import org.fossify.commons.extensions.getCustomizeColorsString +import org.fossify.commons.extensions.getProperPrimaryColor +import org.fossify.commons.extensions.isOrWasThankYouInstalled +import org.fossify.commons.extensions.launchPurchaseThankYouIntent +import org.fossify.commons.extensions.showErrorToast +import org.fossify.commons.extensions.showPickSecondsDialog +import org.fossify.commons.extensions.toast +import org.fossify.commons.extensions.updateTextColors +import org.fossify.commons.extensions.viewBinding +import org.fossify.commons.helpers.ExportResult import org.fossify.commons.helpers.IS_CUSTOMIZING_COLORS import org.fossify.commons.helpers.MINUTE_SECONDS import org.fossify.commons.helpers.NavigationIcon +import org.fossify.commons.helpers.TAB_LAST_USED +import org.fossify.commons.helpers.ensureBackgroundThread import org.fossify.commons.helpers.isTiramisuPlus import org.fossify.commons.models.RadioItem +import java.io.IOException import java.util.Locale import kotlin.system.exitProcess class SettingsActivity : SimpleActivity() { private val binding: ActivitySettingsBinding by viewBinding(ActivitySettingsBinding::inflate) + private val exportActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.CreateDocument(EXPORT_BACKUP_MIME_TYPE)) { uri -> + if (uri == null) return@registerForActivityResult + ensureBackgroundThread { + try { + exportDataTo(uri) + } catch (e: IOException) { + showErrorToast(e) + } + } + } + + private val importActivityResultLauncher = + registerForActivityResult(ActivityResultContracts.OpenDocument()) { uri -> + if (uri == null) return@registerForActivityResult + ensureBackgroundThread { + try { + importData(uri) + } catch (e: Exception) { + showErrorToast(e) + } + } + } override fun onCreate(savedInstanceState: Bundle?) { isMaterialActivity = true super.onCreate(savedInstanceState) setContentView(binding.root) - updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false) + updateMaterialActivityViews( + mainCoordinatorLayout = binding.settingsCoordinator, + nestedView = binding.settingsHolder, + useTransparentNavigation = true, + useTopSearchMenu = false + ) setupMaterialScrollListener(binding.settingsNestedScrollview, binding.settingsToolbar) } @@ -36,6 +101,7 @@ class SettingsActivity : SimpleActivity() { setupCustomizeColors() setupUseEnglish() setupLanguage() + setupDefaultTab() setupPreventPhoneFromSleeping() setupStartWeekOn() setupAlarmMaxReminder() @@ -44,6 +110,8 @@ class SettingsActivity : SimpleActivity() { setupTimerMaxReminder() setupIncreaseVolumeGradually() setupCustomizeWidgetColors() + setupExportData() + setupImportData() updateTextColors(binding.settingsHolder) arrayOf( @@ -82,12 +150,44 @@ class SettingsActivity : SimpleActivity() { private fun setupLanguage() { binding.settingsLanguage.text = Locale.getDefault().displayLanguage - binding.settingsLanguageHolder.beVisibleIf(isTiramisuPlus()) - binding.settingsLanguageHolder.setOnClickListener { - launchChangeAppLanguageIntent() + if (isTiramisuPlus()) { + binding.settingsLanguageHolder.beVisible() + binding.settingsLanguageHolder.setOnClickListener { + launchChangeAppLanguageIntent() + } + } else { + binding.settingsLanguageHolder.beGone() } } + private fun setupDefaultTab() { + binding.settingsDefaultTab.text = getDefaultTabText() + binding.settingsDefaultTabHolder.setOnClickListener { + val items = arrayListOf( + RadioItem(TAB_CLOCK, getString(R.string.clock)), + RadioItem(TAB_ALARM, getString(org.fossify.commons.R.string.alarm)), + RadioItem(TAB_STOPWATCH, getString(R.string.stopwatch)), + RadioItem(TAB_TIMER, getString(R.string.timer)), + RadioItem(TAB_LAST_USED, getString(org.fossify.commons.R.string.last_used_tab)) + ) + + RadioGroupDialog(this@SettingsActivity, items, config.defaultTab) { + config.defaultTab = it as Int + binding.settingsDefaultTab.text = getDefaultTabText() + } + } + } + + private fun getDefaultTabText() = getString( + when (config.defaultTab) { + TAB_CLOCK -> R.string.clock + TAB_ALARM -> org.fossify.commons.R.string.alarm + TAB_STOPWATCH -> R.string.stopwatch + TAB_TIMER -> R.string.timer + else -> org.fossify.commons.R.string.last_used_tab + } + ) + private fun setupPreventPhoneFromSleeping() { binding.settingsPreventPhoneFromSleeping.isChecked = config.preventPhoneFromSleeping binding.settingsPreventPhoneFromSleepingHolder.setOnClickListener { @@ -170,11 +270,13 @@ class SettingsActivity : SimpleActivity() { } private fun updateAlarmMaxReminderText() { - binding.settingsAlarmMaxReminder.text = formatSecondsToTimeString(config.alarmMaxReminderSecs) + binding.settingsAlarmMaxReminder.text = + formatSecondsToTimeString(config.alarmMaxReminderSecs) } private fun updateTimerMaxReminderText() { - binding.settingsTimerMaxReminder.text = formatSecondsToTimeString(config.timerMaxReminderSecs) + binding.settingsTimerMaxReminder.text = + formatSecondsToTimeString(config.timerMaxReminderSecs) } private fun setupCustomizeWidgetColors() { @@ -185,4 +287,77 @@ class SettingsActivity : SimpleActivity() { } } } + + private fun setupExportData() { + binding.settingsExportDataHolder.setOnClickListener { + tryExportData() + } + } + + private fun setupImportData() { + binding.settingsImportDataHolder.setOnClickListener { + tryImportData() + } + } + + private fun exportDataTo(outputUri: Uri) { + val alarms = dbHelper.getAlarms() + val timers = timerDb.getTimers() + if (alarms.isEmpty() && timers.isEmpty()) { + toast(org.fossify.commons.R.string.no_entries_for_exporting) + } else { + ExportHelper(this).exportData( + backup = AlarmTimerBackup(alarms, timers), + outputUri = outputUri, + ) { + toast( + when (it) { + ExportResult.EXPORT_OK -> org.fossify.commons.R.string.exporting_successful + else -> org.fossify.commons.R.string.exporting_failed + } + ) + } + } + } + + private fun tryExportData() { + ExportDataDialog(this, config.lastDataExportPath) { file -> + try { + exportActivityResultLauncher.launch(file.name) + } catch (e: ActivityNotFoundException) { + toast( + id = org.fossify.commons.R.string.system_service_disabled, + length = Toast.LENGTH_LONG + ) + } catch (e: Exception) { + showErrorToast(e) + } + } + } + + private fun tryImportData() { + try { + importActivityResultLauncher.launch(IMPORT_BACKUP_MIME_TYPES.toTypedArray()) + } catch (e: ActivityNotFoundException) { + toast(org.fossify.commons.R.string.system_service_disabled, Toast.LENGTH_LONG) + } catch (e: Exception) { + showErrorToast(e) + } + } + + private fun importData(uri: Uri) { + val result = ImportHelper( + context = this, + dbHelper = DBHelper.dbInstance!!, + timerHelper = TimerHelper(this) + ).importData(uri) + + toast( + when (result) { + ImportHelper.ImportResult.IMPORT_OK -> org.fossify.commons.R.string.importing_successful + ImportHelper.ImportResult.IMPORT_INCOMPLETE -> org.fossify.commons.R.string.no_new_entries_for_importing + ImportHelper.ImportResult.IMPORT_FAIL -> org.fossify.commons.R.string.no_items_found + } + ) + } } diff --git a/app/src/main/kotlin/org/fossify/clock/adapters/ViewPagerAdapter.kt b/app/src/main/kotlin/org/fossify/clock/adapters/ViewPagerAdapter.kt index 17c8a0f8..d5cb5fba 100644 --- a/app/src/main/kotlin/org/fossify/clock/adapters/ViewPagerAdapter.kt +++ b/app/src/main/kotlin/org/fossify/clock/adapters/ViewPagerAdapter.kt @@ -34,34 +34,34 @@ class ViewPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount() = TABS_COUNT private fun getFragment(position: Int) = when (position) { - 0 -> ClockFragment() - 1 -> AlarmFragment() - 2 -> StopwatchFragment() - 3 -> TimerFragment() + TAB_CLOCK_INDEX -> ClockFragment() + TAB_ALARM_INDEX -> AlarmFragment() + TAB_STOPWATCH_INDEX -> StopwatchFragment() + TAB_TIMER_INDEX -> TimerFragment() else -> throw RuntimeException("Trying to fetch unknown fragment id $position") } fun showAlarmSortDialog() { - (fragments[TAB_ALARM] as? AlarmFragment)?.showSortingDialog() + (fragments[TAB_ALARM_INDEX] as? AlarmFragment)?.showSortingDialog() } fun updateClockTabAlarm() { - (fragments[TAB_CLOCK] as? ClockFragment)?.updateAlarm() + (fragments[TAB_CLOCK_INDEX] as? ClockFragment)?.updateAlarm() } fun updateAlarmTabAlarmSound(alarmSound: AlarmSound) { - (fragments[TAB_ALARM] as? AlarmFragment)?.updateAlarmSound(alarmSound) + (fragments[TAB_ALARM_INDEX] as? AlarmFragment)?.updateAlarmSound(alarmSound) } fun updateTimerTabAlarmSound(alarmSound: AlarmSound) { - (fragments[TAB_TIMER] as? TimerFragment)?.updateAlarmSound(alarmSound) + (fragments[TAB_TIMER_INDEX] as? TimerFragment)?.updateAlarmSound(alarmSound) } fun updateTimerPosition(timerId: Int) { - (fragments[TAB_TIMER] as? TimerFragment)?.updatePosition(timerId) + (fragments[TAB_TIMER_INDEX] as? TimerFragment)?.updatePosition(timerId) } fun startStopWatch() { - (fragments[TAB_STOPWATCH] as? StopwatchFragment)?.startStopWatch() + (fragments[TAB_STOPWATCH_INDEX] as? StopwatchFragment)?.startStopWatch() } } diff --git a/app/src/main/kotlin/org/fossify/clock/dialogs/ExportDataDialog.kt b/app/src/main/kotlin/org/fossify/clock/dialogs/ExportDataDialog.kt new file mode 100644 index 00000000..a61d401e --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/dialogs/ExportDataDialog.kt @@ -0,0 +1,76 @@ +package org.fossify.clock.dialogs + +import android.annotation.SuppressLint +import androidx.appcompat.app.AlertDialog +import org.fossify.clock.R +import org.fossify.clock.databinding.DialogExportDataBinding +import org.fossify.clock.extensions.config +import org.fossify.clock.helpers.DATA_EXPORT_EXTENSION +import org.fossify.commons.activities.BaseSimpleActivity +import org.fossify.commons.extensions.getAlertDialogBuilder +import org.fossify.commons.extensions.getCurrentFormattedDateTime +import org.fossify.commons.extensions.getParentPath +import org.fossify.commons.extensions.internalStoragePath +import org.fossify.commons.extensions.isAValidFilename +import org.fossify.commons.extensions.setupDialogStuff +import org.fossify.commons.extensions.showKeyboard +import org.fossify.commons.extensions.toast +import org.fossify.commons.extensions.value +import org.fossify.commons.helpers.ensureBackgroundThread +import java.io.File + +@SuppressLint("SetTextI18n") +class ExportDataDialog( + private val activity: BaseSimpleActivity, + path: String, + private val callback: (file: File) -> Unit, +) { + + companion object { + private const val EXPORT_FILE_NAME = "alarms_and_timers" + } + + private val realPath = path.ifEmpty { activity.internalStoragePath } + private val config = activity.config + + init { + val view = DialogExportDataBinding.inflate(activity.layoutInflater, null, false).apply { + exportDataFilename.setText("${EXPORT_FILE_NAME}_${activity.getCurrentFormattedDateTime()}") + } + + activity.getAlertDialogBuilder() + .setPositiveButton(org.fossify.commons.R.string.ok, null) + .setNegativeButton(org.fossify.commons.R.string.cancel, null) + .apply { + activity.setupDialogStuff( + view = view.root, + dialog = this, + titleId = R.string.settings_export_data + ) { alertDialog -> + alertDialog.showKeyboard(view.exportDataFilename) + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + val filename = view.exportDataFilename.value + when { + filename.isEmpty() -> activity.toast(org.fossify.commons.R.string.empty_name) + filename.isAValidFilename() -> { + val file = File(realPath, "$filename$DATA_EXPORT_EXTENSION") + if (file.exists()) { + activity.toast(org.fossify.commons.R.string.name_taken) + return@setOnClickListener + } + + ensureBackgroundThread { + config.lastDataExportPath = file.absolutePath.getParentPath() + callback(file) + alertDialog.dismiss() + } + } + + else -> activity.toast(org.fossify.commons.R.string.invalid_name) + } + } + } + } + } +} + diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt b/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt index 1f5fa7de..873006a7 100644 --- a/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt +++ b/app/src/main/kotlin/org/fossify/clock/helpers/Config.kt @@ -107,6 +107,10 @@ class Config(context: Context) : BaseConfig(context) { get() = prefs.getBoolean(WAS_INITIAL_WIDGET_SET_UP, false) set(wasInitialWidgetSetUp) = prefs.edit().putBoolean(WAS_INITIAL_WIDGET_SET_UP, wasInitialWidgetSetUp).apply() + var lastDataExportPath: String + get() = prefs.getString(LAST_DATA_EXPORT_PATH, "")!! + set(lastDataExportPath) = prefs.edit().putString(LAST_DATA_EXPORT_PATH, lastDataExportPath).apply() + var firstDayOfWeek: Int get() { val defaultFirstDayOfWeek = Calendar.getInstance(Locale.getDefault()).firstDayOfWeek diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt b/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt index b4bf264a..92c67e1f 100644 --- a/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt +++ b/app/src/main/kotlin/org/fossify/clock/helpers/Constants.kt @@ -26,6 +26,8 @@ const val INCREASE_VOLUME_GRADUALLY = "increase_volume_gradually" const val ALARMS_SORT_BY = "alarms_sort_by" const val STOPWATCH_LAPS_SORT_BY = "stopwatch_laps_sort_by" const val WAS_INITIAL_WIDGET_SET_UP = "was_initial_widget_set_up" +const val DATA_EXPORT_EXTENSION = ".json" +const val LAST_DATA_EXPORT_PATH = "last_alarms_export_path" const val FIRST_DAY_OF_WEEK = "first_day_of_week" const val TABS_COUNT = 4 @@ -51,10 +53,15 @@ const val EARLY_ALARM_DISMISSAL_INTENT_ID = 10002 const val EARLY_ALARM_NOTIF_ID = 10003 const val OPEN_TAB = "open_tab" -const val TAB_CLOCK = 0 -const val TAB_ALARM = 1 -const val TAB_STOPWATCH = 2 -const val TAB_TIMER = 3 +const val TAB_CLOCK = 1 +const val TAB_ALARM = 2 +const val TAB_STOPWATCH = 4 +const val TAB_TIMER = 8 +const val TAB_CLOCK_INDEX = 0 +const val TAB_ALARM_INDEX = 1 +const val TAB_STOPWATCH_INDEX = 2 +const val TAB_TIMER_INDEX = 3 + const val TIMER_ID = "timer_id" const val INVALID_TIMER_ID = -1 @@ -85,6 +92,17 @@ val DAY_BIT_MAP = mapOf( Calendar.SATURDAY to SATURDAY_BIT, ) +// Import/export +const val EXPORT_BACKUP_MIME_TYPE = "application/json" +val IMPORT_BACKUP_MIME_TYPES = buildList { + add("application/json") + if (!isPiePlus()) { + // Workaround for https://github.com/FossifyOrg/Messages/issues/88 + add("application/octet-stream") + } +} + + fun getDefaultTimeZoneTitle(id: Int) = getAllTimeZones().firstOrNull { it.id == id }?.title ?: "" fun getPassedSeconds(): Int { @@ -173,12 +191,12 @@ fun getAllTimeZones() = arrayListOf( MyTimeZone(37, "GMT+02:00 Windhoek", "Africa/Windhoek"), MyTimeZone(38, "GMT+02:00 Amman", "Asia/Amman"), MyTimeZone(39, "GMT+02:00 Athens", "Europe/Athens"), - MyTimeZone(40, "GMT+02:00 Istanbul", "Europe/Istanbul"), MyTimeZone(41, "GMT+02:00 Beirut", "Asia/Beirut"), MyTimeZone(42, "GMT+02:00 Cairo", "Africa/Cairo"), MyTimeZone(43, "GMT+02:00 Helsinki", "Europe/Helsinki"), MyTimeZone(44, "GMT+02:00 Jerusalem", "Asia/Jerusalem"), MyTimeZone(45, "GMT+02:00 Harare", "Africa/Harare"), + MyTimeZone(40, "GMT+03:00 Istanbul", "Europe/Istanbul"), MyTimeZone(46, "GMT+03:00 Minsk", "Europe/Minsk"), MyTimeZone(47, "GMT+03:00 Baghdad", "Asia/Baghdad"), MyTimeZone(48, "GMT+03:00 Moscow", "Europe/Moscow"), diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/ExportHelper.kt b/app/src/main/kotlin/org/fossify/clock/helpers/ExportHelper.kt new file mode 100644 index 00000000..5e5513a7 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/helpers/ExportHelper.kt @@ -0,0 +1,34 @@ +package org.fossify.clock.helpers + +import android.content.Context +import android.net.Uri +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.encodeToStream +import org.fossify.clock.models.AlarmTimerBackup +import org.fossify.commons.helpers.ExportResult + +class ExportHelper(private val context: Context) { + + @OptIn(ExperimentalSerializationApi::class) + fun exportData( + backup: AlarmTimerBackup, + outputUri: Uri?, + callback: (result: ExportResult) -> Unit, + ) { + if (outputUri == null) { + callback.invoke(ExportResult.EXPORT_FAIL) + return + } + + try { + val json = Json { encodeDefaults = true } + context.contentResolver.openOutputStream(outputUri)?.use { out -> + json.encodeToStream(backup, out) + callback.invoke(ExportResult.EXPORT_OK) + } ?: throw NullPointerException("Output stream is null") + } catch (e: Exception) { + callback.invoke(ExportResult.EXPORT_FAIL) + } + } +} diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt b/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt new file mode 100644 index 00000000..bcb524d7 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt @@ -0,0 +1,109 @@ +package org.fossify.clock.helpers + +import android.content.Context +import android.net.Uri +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.decodeFromStream +import org.fossify.clock.models.Alarm +import org.fossify.clock.models.AlarmTimerBackup +import org.fossify.clock.models.Timer +import org.fossify.commons.extensions.showErrorToast + +class ImportHelper( + private val context: Context, + private val dbHelper: DBHelper, + private val timerHelper: TimerHelper, +) { + + enum class ImportResult { + IMPORT_INCOMPLETE, + IMPORT_FAIL, + IMPORT_OK + } + + @OptIn(ExperimentalSerializationApi::class) + fun importData(uri: Uri): ImportResult { + return try { + context.contentResolver.openInputStream(uri)?.use { inputStream -> + val backup = Json.decodeFromStream(inputStream) + val importedAlarms = insertAlarms(backup.alarms) + val importedTimers = insertTimers(backup.timers) + when { + importedAlarms > 0 || importedTimers > 0 -> ImportResult.IMPORT_OK + importedAlarms == 0 && importedTimers == 0 -> ImportResult.IMPORT_INCOMPLETE + else -> ImportResult.IMPORT_FAIL + } + } ?: ImportResult.IMPORT_FAIL + } catch (e: Exception) { + context.showErrorToast(e) + ImportResult.IMPORT_FAIL + } + } + + private fun insertAlarms(alarms: List): Int { + val existingAlarms = dbHelper.getAlarms() + var insertedCount = 0 + alarms.forEach { alarm -> + if (!isAlarmAlreadyInserted(alarm, existingAlarms)) { + if (dbHelper.insertAlarm(alarm) != -1) { + insertedCount++ + } + } + } + return insertedCount + } + + private fun insertTimers(timers: List): Int { + var insertedCount = 0 + timers.forEach { timer -> + timerHelper.getTimers { existingTimers -> + timer.id = if (existingTimers.isNotEmpty()) { + existingTimers.last().id?.plus(1) + } else { + 1 + } + if (!isTimerAlreadyInserted(timer, existingTimers)) { + timerHelper.insertOrUpdateTimer(timer) { id -> + if (id != -1L) { + insertedCount++ + } + } + } + } + } + return insertedCount + } + + private fun isAlarmAlreadyInserted(alarm: Alarm, existingAlarms: List): Boolean { + for (existingAlarm in existingAlarms) { + if (alarm.timeInMinutes == existingAlarm.timeInMinutes && + alarm.days == existingAlarm.days && + alarm.vibrate == existingAlarm.vibrate && + alarm.soundTitle == existingAlarm.soundTitle && + alarm.soundUri == existingAlarm.soundUri && + alarm.label == existingAlarm.label && + alarm.oneShot == existingAlarm.oneShot + ) { + return true + } + } + return false + } + + private fun isTimerAlreadyInserted(timer: Timer, existingTimers: List): Boolean { + for (existingTimer in existingTimers) { + if (timer.seconds == existingTimer.seconds && + timer.vibrate == existingTimer.vibrate && + timer.soundUri == existingTimer.soundUri && + timer.soundTitle == existingTimer.soundTitle && + timer.label == existingTimer.label && + timer.createdAt == existingTimer.createdAt + ) { + return true + } + } + return false + } +} + diff --git a/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt b/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt index fc939900..9d068411 100644 --- a/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt +++ b/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt @@ -3,6 +3,7 @@ package org.fossify.clock.models import androidx.annotation.Keep @Keep +@kotlinx.serialization.Serializable data class Alarm( var id: Int, var timeInMinutes: Int, diff --git a/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt b/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt new file mode 100644 index 00000000..c7deac16 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt @@ -0,0 +1,10 @@ +package org.fossify.clock.models + +import androidx.annotation.Keep + +@Keep +@kotlinx.serialization.Serializable +data class AlarmTimerBackup( + val alarms: List, + val timers: List, +) diff --git a/app/src/main/kotlin/org/fossify/clock/models/Timer.kt b/app/src/main/kotlin/org/fossify/clock/models/Timer.kt index f20dbe18..7899a787 100644 --- a/app/src/main/kotlin/org/fossify/clock/models/Timer.kt +++ b/app/src/main/kotlin/org/fossify/clock/models/Timer.kt @@ -6,6 +6,7 @@ import androidx.room.PrimaryKey @Entity(tableName = "timers") @Keep +@kotlinx.serialization.Serializable data class Timer( @PrimaryKey(autoGenerate = true) var id: Int?, var seconds: Int, diff --git a/app/src/main/kotlin/org/fossify/clock/models/TimerState.kt b/app/src/main/kotlin/org/fossify/clock/models/TimerState.kt index 1737e9d4..26b70337 100644 --- a/app/src/main/kotlin/org/fossify/clock/models/TimerState.kt +++ b/app/src/main/kotlin/org/fossify/clock/models/TimerState.kt @@ -3,16 +3,21 @@ package org.fossify.clock.models import androidx.annotation.Keep @Keep +@kotlinx.serialization.Serializable sealed class TimerState { @Keep + @kotlinx.serialization.Serializable object Idle : TimerState() @Keep + @kotlinx.serialization.Serializable data class Running(val duration: Long, val tick: Long) : TimerState() @Keep + @kotlinx.serialization.Serializable data class Paused(val duration: Long, val tick: Long) : TimerState() @Keep + @kotlinx.serialization.Serializable object Finished : TimerState() } diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 78c76ed8..0c8e057c 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -133,6 +133,29 @@ + + + + + + + + - + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_export_data.xml b/app/src/main/res/layout/dialog_export_data.xml new file mode 100644 index 00000000..392ef38d --- /dev/null +++ b/app/src/main/res/layout/dialog_export_data.xml @@ -0,0 +1,27 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 1da18dd8..b2573ac1 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -43,4 +43,12 @@ زيادة الصوت تدريجيا كيف يمكنني تغيير فرز اللفات في علامة التبويب ساعة التوقيت؟ ما عليك سوى النقر فوق أي من الأعمدة ، مما يجعل الدورات مرتبة حسب العمود المحدد. بنقرات إضافية ، يمكنك التبديل بين الفرز التصاعدي والتنازلي. - + الساعة + الساعة + المؤقت + أضف منبهًا + أضف مؤقتًا + واجهة الساعة + واجهة المنبه + واجهة المؤقت + \ No newline at end of file diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 66038f3b..86cb455b 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -1,50 +1,50 @@ Часовник - Времева зона + Часови пояс Вибрация Не е избран ден Часовник - Таймер + Отброяване Секундомер - Стартирай хронометъра + Старт на секундомера Обиколка Секундомерът е спрян - Таймерът е спрян - Максимално време за напомняне + Отброяването е спряно + Продължителност на напомнянето Времето изтече Час и дата Използване на сянка на текста - Приплъзнете надясно за да отхвърлите или наляво, за да отложите. - Ред на създаване - Време за алармата - Ден и час на алармата + Приплъзнете надясно за изключване, наляво за отлагане. + Реда на създаване + Часа на будилника + Деня и часа на будилника Аналогов часовник Цифров часовник - Алармата е отхвърлена - Избери таймер за отхвърляне - Избери аларма за отхвърляне - Алармата е създадена - Алармата е отложена от %s - Няма намерени аларми - Няма намерени таймери - Предстояща аларма - Ранно изключване на алармата - Таймерите са включени - Таймерът за %s е включен - Нов таймер + Будилникът е изключен + Изберете отброяване, което да изключите + Изберете будилник, което да изключите + Будилникът е създаден + Будилникът е отложен с %s + Липсват будилници + Липсват отброявания + Предстоящ будилник + Ранно изключване на будилник + Отброяванията са включени + Отброяването за %s е включено + Ново отброяване - %d таймер е включен - %d таймери са включени + %d отброяване е включено + %d отброявания са включени Часовник - Аларма - Таб \"Хронометър - Таймер - Покажи секунди - Постепенно увеличавай звука - Как мога да променя сортирането на обиколките на секундомера\? - Просто кликнете на някоя от колонките, това ще ги сортира по тази колонка. С допълнителни кликвания можете да превключвате между възходящо и низходящо сортиране. - Добавяне на таймер - Добавяне на аларма - + Будилник + Секундомер + Отброяване + Показване на секундите + Постепенно усилване на звука + Как да променя сортирането на обиколките на секундомера? + Просто докоснете на някоя от колоните, така ще сортирате по нея. С допълнителни докосвания можете да превключвате между възходящо и низходящо сортиране. + Добавяне на отброяване + Добавяне на будилник + \ No newline at end of file diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 44f79b0b..e28d5959 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -14,7 +14,7 @@ El temps ha caducat Rellotge i data Utilitza l\'ombra del text - Feu lliscar el dit cap a la dreta per ignorar, cap a l\'esquerra per posposar. + Feu lliscar el dit cap a la dreta per a ignorar, cap a l\'esquerra per a posposar. Ordre de creació Hora d\'alarma Dia i hora d\'alarma @@ -34,6 +34,7 @@ Temporitzador nou %d temporitzador en marxa + %d temporitzadors en marxa %d temporitzadors en marxa Pestanya del rellotge @@ -47,4 +48,4 @@ Afegeix un temporitzador Rellotge Afegeix una alarma - + \ No newline at end of file diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 75cf899e..9b1886ee 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -18,4 +18,8 @@ Vis sekunder Hvordan kan jeg ændre sortering af mellemtider i stopuret? Klik på den kolonne der skal sorteres efter. Med flere klik kan du skifte mellem stigende og faldende rækkefølge. - + Ur + Start stopur + Klokketslet og dato + Stopur + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index dd8627dd..7c0dc69a 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -45,4 +45,6 @@ Ansteigende Lautstärke Wie kann die Sortierung der Laschen der Stoppuhr geändert werden? Einfach auf eine der Spalten klicken, das wird die Sortierung entsprechend der Spalte anpassen. Weitere Klicks schalten zwischen auf- und absteigender Sortierung um. - + Timer + Timer + \ No newline at end of file diff --git a/app/src/main/res/values-ga/strings.xml b/app/src/main/res/values-ga/strings.xml new file mode 100644 index 00000000..901ff80e --- /dev/null +++ b/app/src/main/res/values-ga/strings.xml @@ -0,0 +1,53 @@ + + + Fad uasta meabhrúcháin + Am caite + Aláram snoozed ag %s + Aláram briste + Roghnaigh uaineadóir le díbhe + Roghnaigh aláram le díbhe + Aláram cruthaithe + Níor aimsíodh aláraim ar bith + Cuir aláram leis + Níor aimsíodh amadóirí ar bith + Cuir uaineadóir leis + + Tá an t-amadóir %d ag rith + Tá %d amadóir ag rith + Tá %d amadóir ag rith + Tá %d amadóir ag rith + Tá %d amadóir ag rith + + Clog + Crios ama + Creathadh + Níl aon lá roghnaithe + Clog + Uaireanta + StopwatchName + Tosaigh stopuaireadóir + Lap + Stop an uaireadóir + Cuireadh stop leis an uaineadóir + Clog agus dáta + Úsáid scáth téacs + Svaidhpeáil ar dheis chun Díbhe, nó ar chlé go Snooze. + Ordú cruthaithe + Am aláraim + Am Lae agus Aláraim + Clog analógach + Clog digiteach + Aláram atá le teacht + Dífhostú aláraim luath + Amadóirí ag rith + Tá an t- amadóir do %s ag rith + Amadóir Nua + Cluaisín clog + Cluaisín aláraim + Cluaisín Stopwatch + Cluaisín uaineadóra + Taispeáin soicindí + Méadaigh an toirt de réir a chéile + Conas is féidir liom sórtáil lap a athrú ag an táb stopwatch? + Just a cliceáil ar aon cheann de na colúin, a dhéanamh ar an laps a shórtáil ag an gcolún a thugtar. Le cad a tharlaíonn nuair breise is féidir leat scoránaigh idir dul suas agus sórtáil íslitheach. + \ No newline at end of file diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 4b1a5b91..a167bf85 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -47,4 +47,5 @@ Odaberi alarm za odbacivanje Alarm je stvoren Odaberi timer za odbacivanje - + Timer + \ No newline at end of file diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index f30a7229..8971d392 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -6,7 +6,7 @@ Horologio digital Scheda de chronometro Horologio e data - Necun dies seligite + Necun die selectionate Alarma create Horologio Necun alarma trovate @@ -20,10 +20,10 @@ Temporisator Scheda de temporisator Adder temporisator - Monstrar le secundas + Monstrar secundas Nove temporisator Adder alarma - Initiar le chronometro + Initiar chronometro Horologio analogic Le temporisator esseva stoppate - + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 483b6c2d..545e818c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -18,17 +18,17 @@ 曜日とアラーム時刻 アナログ時計 デジタル時計 - アラームが破棄されました + アラームを消去しました アラームが見つかりません アラームを追加 タイマーが見つかりません タイマーを追加 今後のアラーム - タイマーが作動中 - タイマー %s が作動中 + タイマーが作動しています + タイマー %s が作動しています 新しいタイマー - %d 個のタイマーが作動中 + %d個のタイマーが作動しています 時計 アラーム @@ -38,4 +38,12 @@ 音量を徐々に大きくする ストップウォッチのタブでラップタイムの並べ替えを行うにはどうすればよいですか? 特定の列をタップすると、その列でラップタイムが並べ替えられます。さらにもう一度タップすると、昇順と降順の切り替えを行えます。 - + 時計 + ストップウォッチ + ストップウォッチを開始 + 消去するアラームを選択してください + アラームを作成しました + %sまでスヌーズ中のアラーム + アラームを事前に消去 + 消去するタイマーを選択してください + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3ea04e70..f90806bd 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1,2 +1,49 @@ - + + 시계 + 타이머 + 스톱워치 시작 + 구간 기록 + 타이머가 중지되었습니다 + 알림 최대 지속시간 + 시간 만료 + 시계 및 날짜 + 텍스트 그림자 사용 + 생성된 순서 + 아날로그 시계 + 디지털 시계 + 해제할 타이머를 선택하세요 + 해제할 알람을 선택하세요 + 알람이 %s에 의해 스누즈되었습니다 + 알람이 해제되었습니다 + 알람이 생성되었습니다 + 알람이 없습니다 + 알람 추가하기 + 타이머가 없습니다 + 타이머 추가하기 + 곧 울릴 알람 + 조기 알람 해제 + 타이머가 실행 중입니다 + + 타이머 %d 개가 실행 중입니다 + + 시계 탭 + 알람 탭 + 타이머 탭 + 음량 점점 크게 울리기 + 초 단위 표시하기 + 스톱워치 탭에서 구간 기록 정렬을 바꾸려면 어떻게 해야하나요? + 시계 + 진동 + 스톱워치 + 선택된 날짜가 없습니다 + 시간대 + 스톱워치가 중지되었습니다 + 오른쪽으로 밀어 해제하거나, 왼쪽으로 밀어 스누즈합니다. + 알람 시간 순서 + 날짜와 알람 시간 순서 + %s 타이머가 실행 중입니다 + 새로운 타이머 + 스톱워치 탭 + 아무 열이나 누르면, 해당 열에 대해 정렬됩니다. 다시 누르면 오름차순과 내림차순 정렬을 바꿀 수 있습니다. + \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 373bfa3e..248025a7 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -9,40 +9,42 @@ Ronde Stopwatch is gestopt Timer is gestopt - Max duur van herinnering + Maximale herinneringsduur Tijd verstreken Klok en datum Tekstschaduw gebruiken - Veeg naar rechts voor uitzetten, of naar links voor uitstellen. + Veeg naar rechts om te sluiten, of naar links om te sluimeren. Aanmaakvolgorde Wektijd Dag en tijd Analoge klok Digitale klok Wekker uitgezet - Timer uitzetten - Wekker uitzetten + Selecteer timer om uit te zetten + Selecteer wekker om uit te zetten Wekker ingesteld Wekker uitgesteld met %s - Geen wekkers + Geen wekkers gevonden Wekker toevoegen - Geen timers + Geen timers gevonden Timer toevoegen Volgende wekker Wekker vroegtijdig uitzetten - Timers lopen - Timer voor %s loopt - Nieuwe Timer + Timers actief + Timer voor %s actief + Nieuwe timer - %d timer loopt - %d timers lopen + %d timer actief + %d timers actief - Tab Klok - Tab Wekker - Tab Stopwatch - Tab Timers + Tabblad klok + Tabblad wekker + Tabblad stopwatch + Tabblad timer Seconden tonen Volume geleidelijk verhogen Hoe kan ik rondetijden sorteren in de stopwatch? Klik op een van de kolommen om de rondetijden te sorteren op basis van die kolom. Klik nogmaals op dezelfde kolom om de sorteervolgorde om te keren. - + Stopwatch + Timer + \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index ad463d37..4e44383c 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -48,4 +48,4 @@ Como posso alterar a ordem das voltas no Cronómetro\? Basta clicar em qualquer uma das colunas e isso fará com que as voltas sejam ordenadas pela coluna especificada. Com cliques adicionais, pode alternar a ordem de entre crescente e decrescente. Descartar alarme cedo - + \ No newline at end of file diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 37499fbd..97411a33 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -12,7 +12,7 @@ Секундомер остановлен Таймер остановлен Максимальная длительность напоминания - Время вышло + Время истекло Часы и дата Использовать затенение текста Смахивание вправо — отключить, влево — отложить. @@ -48,5 +48,5 @@ Показывать секунды Нарастание громкости Как я могу изменить сортировку кругов во вкладке секундомера? - Просто нажмите на любую из колонок, и круги отсортируются по этой колонке. Дополнительными нажатиями можно переключаться между сортировкой по возрастанию и по убыванию. - + Просто нажмите на любой из столбцов, и круги отсортируются по этому столбцу. Дополнительными нажатиями можно переключаться между сортировкой по возрастанию и по убыванию. + \ No newline at end of file diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index b3dd0b91..b4b33c99 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -23,7 +23,7 @@ Alarmet har avvisats Välj timer att avfärda Välj alarm att avfärda - Alarm skapat + Alarmet har skapats Alarmet snoozar %s Inga alarm hittades Lägg till alarm @@ -46,4 +46,5 @@ Höj volymen gradvis Hur kan jag ändra sortering av varv i fliken stoppur\? Klicka bara på någon av kolumnerna för att sortera varven efter den aktuella kolumnen. Med ytterligare klick kan du växla mellan stigande och fallande sortering. - + Timer + \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 1968a289..276d8fd2 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1,7 +1,7 @@ Đồng hồ - Không có ngày nào được chọn + Chưa chọn ngày nào Đồng hồ bấm giờ đã bị dừng Vuốt sang phải để Loại bỏ hoặc sang trái để Tạm ẩn. Múi giờ @@ -23,7 +23,7 @@ Đồng hồ kỹ thuật số Chỉ cần nhấn vào bất kỳ cột nào, điều đó sẽ làm cho các vòng được sắp xếp theo cột đã cho. Với những lần nhấn bổ sung, bạn có thể chuyển đổi giữa sắp xếp tăng dần và giảm dần. Chọn hẹn giờ để loại bỏ - Đã loại bỏ báo thức + Đã bỏ qua báo thức Chọn báo thức để loại bỏ Đã tạo báo thức Đã tạm ẩn báo thức %s @@ -40,10 +40,10 @@ %d bộ hẹn giờ đang chạy Danh mục đồng hồ - Danh mục báo thức + Tab báo thức Danh mục đếm giờ Danh mục hẹn giờ Hiển thị giây Tăng âm lượng dần dần Làm cách nào tôi có thể thay đổi cách sắp xếp vòng ở danh mục đồng hồ bấm giờ? - + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 8101f61f..af3eb57d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -2,7 +2,7 @@ 时钟 时区 - 震动 + 振动 未选择哪一天 时钟 定时器 @@ -46,4 +46,4 @@ 音量渐增 秒表页面分段的排序如何更改? 只要点击任一栏位,就会依据选定的栏位做排序。再多点一下,还能切换递增或者递减顺序。 - + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 30be952a..2fb366e7 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1,6 +1,6 @@ - 簡易時鐘 + 時鐘 時區 震動 未選擇哪一天 @@ -21,4 +21,29 @@ 音量漸增 碼錶頁面分段的排序如何變更? 只要點擊任一欄位,就會依選定的欄位做排序。再多點一下,還能切換遞增或遞減的排序。 - + 提早解除鬧鐘 + 時鐘 + 計時器 + 開始計時 + 解除鬧鐘 + 選取要解除的計時器 + 選取要解除的鬧鐘 + 已建立鬧鐘 + 鬧鐘被 %s 以貪睡延後 + 找不到鬧鐘 + 新增鬧鐘 + 找不到計時器 + 新增計時器 + 即將到來的鬧鐘 + 計時器正在運作 + %s 的計時器正在運作 + 新的計時器 + + %d 個計時器正在運作 + + 建立順序 + 鬧鐘時間 + 日期與鬧鐘時間 + 類比時鐘 + 數位時鐘 + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1bcde8ab..5df0ed1b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,6 +50,8 @@ Timer tab Show seconds Increase volume gradually + Import alarms and timers + Export alarms and timers How can I change lap sorting at the stopwatch tab? diff --git a/build.gradle.kts b/build.gradle.kts index 9a736eea..f09a2174 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,7 @@ plugins { alias(libs.plugins.android).apply(false) alias(libs.plugins.kotlinAndroid).apply(false) + alias(libs.plugins.kotlinSerialization).apply(false) alias(libs.plugins.ksp).apply(false) + alias(libs.plugins.detekt).apply(false) } diff --git a/fastlane/metadata/android/bg/title.txt b/fastlane/metadata/android/bg/title.txt new file mode 100644 index 00000000..16fe316b --- /dev/null +++ b/fastlane/metadata/android/bg/title.txt @@ -0,0 +1 @@ +Fossify Clock diff --git a/fastlane/metadata/android/ca/changelogs/1.txt b/fastlane/metadata/android/ca/changelogs/1.txt new file mode 100644 index 00000000..aa2a1fa4 --- /dev/null +++ b/fastlane/metadata/android/ca/changelogs/1.txt @@ -0,0 +1 @@ +* Llançament inicial. diff --git a/fastlane/metadata/android/ca/full_description.txt b/fastlane/metadata/android/ca/full_description.txt new file mode 100644 index 00000000..ad1e892d --- /dev/null +++ b/fastlane/metadata/android/ca/full_description.txt @@ -0,0 +1,32 @@ +Presentem el Fossify Clock, l'acompanyant definitiu de control del temps dissenyat per a millorar les vostres rutines diàries i promoure hàbits millors de son. Amb multitud de funcions adaptades a les vostres necessitats, el Fossify Clock s'integra perfectament a la vostra vida, oferint una comoditat i versatilitat incomparables. + +⌚ CONTROL DEL TEMPS MULTIFUNCIONAL: +Experimenteu la potència de la gestió versàtil del temps amb el Fossify Clock. Des de servir com a giny de rellotge fins a funcionar com a despertador i cronòmetre, aquesta aplicació és l'eina de referència per a regular les activitats diàries i millorar l'estil de vida general. + +⏰ ALARMA PLENA DE CARACTERÍSTIQUES: +Desperteu-vos fresc amb les característiques integrals d'alarma del Fossify Clock. Establiu diverses alarmes amb opcions com selecció de dia, commutador de vibració, etiquetes personalitzades i personalització de tons de trucada. Gaudiu d'un augment gradual del volum i d'un botó de posposar personalitzable per a una experiència agradable en despertar. Amb una interfície fàcil d'usar, la configuració d'alarmes mai ha estat tan fàcil. + +⏱️ CRONÒMETRE PRÀCTIC: +Feu un seguiment de les vostres activitats amb precisió utilitzant la funció de cronòmetre del Fossify Clock. Mesureu períodes més llargs o voltes individuals sense esforç. També podeu ordenar les voltes en ordre ascendent o descendent. + +⏳ FUNCIONALITAT PRECISA DEL TEMPORITZADOR: +Seguiu les tasques amb la funció versàtil del temporitzador del Fossify Clock. Personalitzeu les preferències de to de trucada, commuteu les vibracions i feu pausa del compte enrere segons les vostres necessitats. Tant si esteu programant intervals de cocció, gestionant sessions d'estudi o assegurant descansos puntuals, el Fossify Clock us dona cobertura amb precisió i facilitat. + +🌈 GINY DE RELLOTGE AMB CARACTERÍSTIQUES PERSONALITZABLES: +Transformeu la pantalla d'inici amb el giny de rellotge personalitzable del Fossify Clock. Ajusteu el color del text, el color de fons i la transparència. Trieu entre rellotge analògic o digital per adaptar-vos al vostre estil i accedir fàcilment a la informació de temps essencial d'un cop d'ull. + +🎨 INTERFÍCIE I TEMES PERSONALITZABLES: +Gaudiu d'una experiència personalitzada amb el «material design» del Fossify Clock i les opcions de tema fosc. Adapteu l'aplicació a les vostres preferències amb colors i temes personalitzables, potenciant la usabilitat i reduint la tensió ocular, especialment en entorns de poca llum. + +🔒 ENFOCAT A LA PRIVADESA: +Tingueu la seguretat de saber que la vostra privadesa està protegida amb el funcionament fora de línia del Fossify Clock. Experimenteu la privadesa, seguretat i estabilitat màxima sense sacrificar la funcionalitat ni la comoditat. + +🌐 SENSE PUBLICITAT I DE CODI OBERT: +Digueu adeu als anuncis intrusius i als permisos innecessaris. El Fossify Clock és sense anuncis, totalment de codi obert, i us atorga un control complet sobre la vostra experiència de control del temps. + +Actualitzeu les vostres habilitats de gestió del temps, optimitzeu les rutines i prioritzeu millor el son amb el Fossify Clock. Descarregueu-lo ara i preneu el control del vostre temps com mai. + +Exploreu més aplicacions de Fossify: https://www.fossify.org +Codi obert: https://www.github.com/FossifyOrg +Uniu-vos a la comunitat a Reddit: https://www.reddit.com/r/Fossify +Connecteu a Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/ca/short_description.txt b/fastlane/metadata/android/ca/short_description.txt new file mode 100644 index 00000000..e62332ec --- /dev/null +++ b/fastlane/metadata/android/ca/short_description.txt @@ -0,0 +1 @@ +Aplicació de rellotge de codi obert, lleuger i amb característiques essencials. diff --git a/fastlane/metadata/android/ca/title.txt b/fastlane/metadata/android/ca/title.txt new file mode 100644 index 00000000..16fe316b --- /dev/null +++ b/fastlane/metadata/android/ca/title.txt @@ -0,0 +1 @@ +Fossify Clock diff --git a/fastlane/metadata/android/cs-CZ/changelogs/1.txt b/fastlane/metadata/android/cs-CZ/changelogs/1.txt new file mode 100644 index 00000000..b3f5c161 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/1.txt @@ -0,0 +1 @@ +* Prvotní vydání. diff --git a/fastlane/metadata/android/cs-CZ/full_description.txt b/fastlane/metadata/android/cs-CZ/full_description.txt new file mode 100644 index 00000000..f356c8b5 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/full_description.txt @@ -0,0 +1,32 @@ +Představujeme Hodiny Fossify – ultimátní nástroj na sledování času navržený pro vylepšení vašich každodenních rutin a pomohl vám s lepším spánkem. Hodiny Fossify obsahují velké množství funkcí přímo pro vaše potřeby, takže se bezproblémově integrují do vašeho života a poskytují bezkonkurenční pohodlí a všestrannost. + +⌚ MULTIFUKNČNÍ ČASOMÍRA: +Vyzkoušejte sílu všestranné správy času pomocí aplikace Hodiny Fossify. Tato aplikace slouží jako widget hodin, budík i stopky a je vaším nástrojem pro regulaci každodenních činností a zlepšení celkového životního stylu. + +⏰ BUDÍK BOHATÝ NA FUNKCE: +Díky rozsáhlým funkcím budíku v aplikaci Hodiny Fossify se můžete probouzet svěží. Nastavte si více budíků s možnostmi, jako je výběr dne, přepínání vibrací, vlastní štítky a přizpůsobení vyzvánění. Vychutnejte si postupné zvyšování hlasitosti a přizpůsobitelné tlačítko odložení budíku pro příjemné probuzení. Díky přívětivému uživatelskému rozhraní nebylo nastavování budíků nikdy jednodušší. + +⏱️ PRAKTICKÉ STOPKY: +Aplikace Hodiny Fossify umožňuje přesné sledování vašich aktivit pomocí funkce stopek. Bez námahy změříte delší časové úseky nebo jednotlivá kola. Své okruhy můžete také seřadit vzestupně nebo sestupně. + +⏳ PŘESNÁ FUNKCE ČASOVAČE: +Díky všestranné funkci časovače aplikace Hodiny Fossify budete mít přehled o svých úkolech. Přizpůsobte si preference vyzvánění, přepínejte vibrace a pozastavujte odpočítávání podle svých potřeb. Ať už časujete intervaly vaření, řídíte studijní sezení nebo zajišťujete včasné přestávky, aplikace Hodiny Fossify vám to umožní s přesností a lehkostí. + +🌈 WIDGET HODIN S PŘIZPŮSOBITELNÝMI FUNKCEMI: +Přeměňte svou domovskou obrazovku pomocí přizpůsobitelného widgetu aplikace Hodiny Fossify. Upravte si barvu textu, barvu pozadí a průhlednost. Vyberte si mezi analogovými nebo digitálními hodinami podle svého stylu a snadno získejte přístup k základním informacím o čase na první pohled. + +🎨 PŘIZPŮSOBITELNÉ ROZHRANÍ A MOTIVY: +Vychutnejte si přizpůsobené prostředí díky Material Designu a možnostem tmavých motivů v aplikaci Hodiny Fossify. Přizpůsobte si aplikaci podle sebe pomocí přizpůsobitelných barev a motivů, což zvyšuje použitelnost a snižuje namáhání očí, zejména v prostředí se slabým osvětlením. + +🔒 PŘÍSTUP ZAMĚŘENÝ PŘEDEVŠÍM NA SOUKROMÍ: +Aplikace Hodiny Fossify funguje v režimu offline a vaše soukromí je chráněno. Zažijte maximální soukromí, bezpečnost a stabilitu, aniž byste museli obětovat funkčnost nebo pohodlí. + +🌐 BEZ REKLAM A S OTEVŘENÝM ZDROJOVÝM KÓDEM: +Rozlučte se s vtíravými reklamami a zbytečnými povoleními. Aplikace Hodiny Fossify je bez reklam, plně open-source a poskytuje vám plnou kontrolu nad vaší časomírou. + +Vylepšete své dovednosti v oblasti správy času, optimalizujte své rutinní postupy a upřednostněte lepší spánek pomocí aplikace Hodiny Fossify. Stáhněte si je nyní a převezměte kontrolu nad svým časem jako nikdy předtím. + +Prozkoumejte další aplikace Fossify: https://www.fossify.org +Otevřený zdrojový kód: https://www.github.com/FossifyOrg +Přidejte se ke komunitě na Redditu: https://www.reddit.com/r/Fossify +Připojte se k Telegramu: https://t.me/Fossify diff --git a/fastlane/metadata/android/cs-CZ/short_description.txt b/fastlane/metadata/android/cs-CZ/short_description.txt new file mode 100644 index 00000000..5666f1df --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/short_description.txt @@ -0,0 +1 @@ +Praktická aplikace hodin s otevřeným zdrojovým kódem a základními funkcemi. diff --git a/fastlane/metadata/android/cs-CZ/title.txt b/fastlane/metadata/android/cs-CZ/title.txt new file mode 100644 index 00000000..b776b839 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/title.txt @@ -0,0 +1 @@ +Hodiny Fossify diff --git a/fastlane/metadata/android/de-DE/changelogs/1.txt b/fastlane/metadata/android/de-DE/changelogs/1.txt new file mode 100644 index 00000000..4ca8d170 --- /dev/null +++ b/fastlane/metadata/android/de-DE/changelogs/1.txt @@ -0,0 +1 @@ +* Erste Veröffentlichung. diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt new file mode 100644 index 00000000..e4e8bf98 --- /dev/null +++ b/fastlane/metadata/android/de-DE/full_description.txt @@ -0,0 +1,32 @@ +Fossify Clock ist der ultimative Begleiter für die Zeitmessung, der deine täglichen Routinen verbessert und deine Schlafgewohnheiten fördert. Mit einer Vielzahl von Funktionen, die auf deine Bedürfnisse zugeschnitten sind, fügt sich Fossify Clock nahtlos in dein Leben ein und bietet unvergleichlichen Komfort und Vielseitigkeit. + +⌚ MULTIFUNKTIONALE ZEITMESSUNG: +Erlebe die Macht des vielseitigen Zeitmanagements mit Fossify Clock. Ob als Uhren-Widget, Wecker oder Stoppuhr – mit dieser App kannst du deine täglichen Aktivitäten regulieren und deinen Lebensstil verbessern. + +⏰ FUNKTIONSREICHER ALARM: +Mit den umfassenden Alarmfunktionen von Fossify Clock wachst du erfrischt auf. Stelle mehrere Alarme mit Optionen wie Tagesauswahl, Vibration, benutzerdefinierte Beschriftung und Klingeltonanpassung ein. Genieße die schrittweise Erhöhung der Lautstärke und eine anpassbare Schlummertaste für ein angenehmes Aufwachen. Dank der bedienfreundlichen Oberfläche war es noch nie so einfach, Alarme einzurichten. + +⏱️ PRAKTISCHE STOPPUHR: +Mit der Stoppuhrfunktion von Fossify Clock kannst du deine Aktivitäten genau verfolgen. Messe mühelos längere Zeiträume oder einzelne Runden. Du kannst deine Runden auch in aufsteigender oder absteigender Reihenfolge sortieren. + +⏳ PRÄZISE TIMER-FUNKTION: +Mit der vielseitigen Timer-Funktion von Fossify Clock behältst du den Überblick über deine Aufgaben. Du kannst den Klingelton einstellen, die Vibration einschalten und die Countdowns anhalten. Ganz gleich, ob du Kochintervalle zeitlich festlegen, Lernsessions verwalten oder rechtzeitig Pausen einlegen willst, Fossify Clock bietet dir Präzision und Leichtigkeit. + +🌈 UHR-WIDGET MIT ANPASSBAREN FUNKTIONEN: +Verändere deinen Startbildschirm mit dem anpassbaren Uhren-Widget von Fossify Clock. Passe Textfarbe, Hintergrundfarbe und Transparenz an. Wähle zwischen analoger oder digitaler Uhr, um deinen Stil zu unterstreichen und die wichtigsten Zeitinformationen auf einen Blick zu sehen. + +🎨 ANPASSBARE OBERFLÄCHE UND FARBSCHEMAS: +Genieße ein individuelles Erlebnis mit dem Material Design und den dunklen Farbschemas von Fossify Clock. Passe die App mit anpassbaren Farben und Farbschemas an deine Vorlieben an, um die Bedienfreundlichkeit zu verbessern und die Augen zu entlasten, besonders in schwach beleuchteten Umgebungen. + +🔒 PRIVATSPHÄRE STEHT AN ERSTER STELLE: +Du kannst sicher sein, dass deine Privatsphäre durch den Offline-Betrieb von Fossify Clock geschützt ist. Erlebe ein Maximum an Privatsphäre, Sicherheit und Stabilität, ohne auf Funktionalität oder Komfort verzichten zu müssen. + +🌐 WERBEFREI & OPEN SOURCE: +Verabschiede dich von aufdringlicher Werbung und unnötigen Berechtigungen. Fossify Clock ist werbefrei, vollständig quelloffen und gibt dir die volle Kontrolle über deine Zeiterfassung. + +Verbessere dein Zeitmanagement, optimiere deine Routinen und sorge für besseren Schlaf mit Fossify Clock. Lade die App jetzt herunter und übernimm die Kontrolle über deine Zeit wie nie zuvor. + +Entdecke weitere Apps von Fossify: https://www.fossify.org +Open-Source-Code: https://www.github.com/FossifyOrg +Tritt der Community auf Reddit bei: https://www.reddit.com/r/Fossify +Verbinde dich auf Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/de-DE/short_description.txt b/fastlane/metadata/android/de-DE/short_description.txt new file mode 100644 index 00000000..927ae412 --- /dev/null +++ b/fastlane/metadata/android/de-DE/short_description.txt @@ -0,0 +1 @@ +Nützliche, schlanke, quelloffene Uhr-App mit grundlegenden Funktionen. diff --git a/fastlane/metadata/android/de-DE/title.txt b/fastlane/metadata/android/de-DE/title.txt new file mode 100644 index 00000000..16fe316b --- /dev/null +++ b/fastlane/metadata/android/de-DE/title.txt @@ -0,0 +1 @@ +Fossify Clock diff --git a/fastlane/metadata/android/es-ES/changelogs/1.txt b/fastlane/metadata/android/es-ES/changelogs/1.txt new file mode 100644 index 00000000..a1f6c8d3 --- /dev/null +++ b/fastlane/metadata/android/es-ES/changelogs/1.txt @@ -0,0 +1 @@ +* Versión inicial. diff --git a/fastlane/metadata/android/es-ES/full_description.txt b/fastlane/metadata/android/es-ES/full_description.txt new file mode 100644 index 00000000..01274f8c --- /dev/null +++ b/fastlane/metadata/android/es-ES/full_description.txt @@ -0,0 +1,32 @@ +Presentamos Fossify Clock – el compañero de cronometraje definitivo diseñado para mejorar sus rutinas diarias y promover mejores hábitos de sueño. Con una multitud de funciones adaptadas a sus necesidades, Fossify Clock se integra perfectamente en su vida, ofreciendo comodidad y versatilidad sin precedentes. + +⌚ CRONOMETRAJE MULTIFUNCIONAL: +Experimente el poder de la gestión del tiempo versátil con Fossify Clock. Desde un widget de reloj hasta un despertador y cronómetro, esta aplicación es tu herramienta preferida para regular tus actividades diarias y mejorar tu estilo de vida en general. + +⏰ ALARMA RICA EN CARACTERÍSTICAS: +Despiértese renovado con las funciones de alarma integrales de Fossify Clock. Configure múltiples alarmas con opciones como selección de día, interruptor de vibración, etiquetas personalizadas y personalización de tonos de llamada. Disfrute de un aumento gradual del volumen y un botón de repetición personalizable para una agradable experiencia de despertar. Con una interfaz fácil de usar, la configuración de alarmas nunca ha sido tan fácil. + +⏱️ CRONÓMETRO CONVENIENTE: +Realiza un seguimiento de tus actividades con precisión utilizando la función de cronómetro de Fossify Clock. Mida períodos más largos o vueltas individuales sin esfuerzo. También puedes ordenar tus vueltas en orden ascendente o descendente. + +⏳ FUNCIONALIDAD DE TEMPORIZADOR PRECISO: +Manténgase al tanto de sus tareas con la versátil función de temporizador de Fossify Clock. Personaliza las preferencias de tonos de llamada, cambia las vibraciones y pausa la cuenta atrás para satisfacer tus necesidades. Ya sea que esté programando intervalos de cocción, administrando sesiones de estudio o asegurando descansos oportunos, Fossify Clock lo tiene cubierto con precisión y facilidad. + +🌈 RELOJ WIDGET CON CARACTERÍSTICAS PERSONALIZABLES: +Transforma tu pantalla de inicio con el widget de reloj personalizable de Fossify Clock. Ajuste el color del texto, el color de fondo y la transparencia. Elija entre reloj analógico o digital para adaptarse a su estilo y acceder fácilmente a la información de tiempo esencial de un vistazo. + +🎨 INTERFAZ PERSONALIZABLE Y TEMAS: +Disfruta de una experiencia personalizada con material design y opciones de temas oscuros de Fossify Clock. Adapta la aplicación a tus preferencias con colores y temas personalizables, mejorando la usabilidad y reduciendo la fatiga visual, especialmente en entornos con poca luz. + +🔒 LA PRIVACIDAD ES LO PRIMERO: +Tenga la seguridad de saber que su privacidad está protegida con el funcionamiento fuera de línea de Fossify Clock. Disfrute de la máxima privacidad, seguridad y estabilidad sin sacrificar funcionalidad o conveniencia. + +🌐 SIN ANUNCIOS Y DE CÓDIGO ABIERTO: +Diga adiós a los anuncios intrusivos y a los permisos innecesarios. Fossify Clock está libre de anuncios, es totalmente de código abierto y le otorga un control completo sobre su experiencia de cronometraje. + +Mejore sus habilidades de gestión del tiempo, optimice sus rutinas y priorice un mejor sueño con Fossify Clock. Descarga ahora y toma el control de tu tiempo como nunca antes. + +Explore más aplicaciones de Fossify: https://www.fossify.org +Código abierto: https://www.github.com/FossifyOrg +Únete a la comunidad en Reddit: https://www.reddit.com/r/Fossify +Conéctese con Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/es-ES/short_description.txt b/fastlane/metadata/android/es-ES/short_description.txt new file mode 100644 index 00000000..3b5adaf6 --- /dev/null +++ b/fastlane/metadata/android/es-ES/short_description.txt @@ -0,0 +1 @@ +Reloj práctico, ligero y de código abierto con funciones esenciales. diff --git a/fastlane/metadata/android/es-ES/title.txt b/fastlane/metadata/android/es-ES/title.txt new file mode 100644 index 00000000..b2d84e19 --- /dev/null +++ b/fastlane/metadata/android/es-ES/title.txt @@ -0,0 +1 @@ +Reloj Fossify diff --git a/fastlane/metadata/android/et/changelogs/1.txt b/fastlane/metadata/android/et/changelogs/1.txt new file mode 100644 index 00000000..c717f93a --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/1.txt @@ -0,0 +1 @@ +* Esmane versioon. diff --git a/fastlane/metadata/android/et/short_description.txt b/fastlane/metadata/android/et/short_description.txt new file mode 100644 index 00000000..1b9afad9 --- /dev/null +++ b/fastlane/metadata/android/et/short_description.txt @@ -0,0 +1 @@ +Mugav ja lihtne avatud lähtekoodil põhinev kell, milles on kõik vajalik olemas. diff --git a/fastlane/metadata/android/et/title.txt b/fastlane/metadata/android/et/title.txt new file mode 100644 index 00000000..21b7076c --- /dev/null +++ b/fastlane/metadata/android/et/title.txt @@ -0,0 +1 @@ +Fossify kell diff --git a/fastlane/metadata/android/eu-ES/changelogs/1.txt b/fastlane/metadata/android/eu-ES/changelogs/1.txt new file mode 100644 index 00000000..5dcf4e7a --- /dev/null +++ b/fastlane/metadata/android/eu-ES/changelogs/1.txt @@ -0,0 +1 @@ +* Lehenengo bertsioa. diff --git a/fastlane/metadata/android/eu-ES/full_description.txt b/fastlane/metadata/android/eu-ES/full_description.txt new file mode 100644 index 00000000..1b3b210d --- /dev/null +++ b/fastlane/metadata/android/eu-ES/full_description.txt @@ -0,0 +1,32 @@ +Fossify erlojua aurkezten dugu: zure eguneroko ohiturak hobetzeko eta lo egiteko ohitura hobeak sustatzeko diseinatutako denbora-konpainia bikaina. Zure beharretara egokitutako funtzio ugarirekin, Fossify erlojua ezin hobeto integratzen da zure bizitzan, erosotasun eta aldakortasun paregabeak eskainiz. + + FUNTZUN ANITZEKO kronometroa: +Bizi ezazu denbora-kudeaketa polifazetikoa Fossify Clock-ekin. Erlojuaren widget gisa jardutetik iratzargailu eta kronometro gisa funtzionatzera, aplikazio hau zure eguneroko jarduerak erregulatzeko eta zure bizimodu orokorra hobetzeko tresna erabilgarria da. + + EZAUGARRI ABERATSEKO ALARMA: +Esnatu freskatu Fossify erlojuaren alarma-funtzio osoekin. Ezarri alarma anitz egun hautatzeko aukerarekin, bibrazio-aldaketa, etiketa pertsonalizatuak eta dei-tonuak pertsonalizatzea. Gozatu bolumena pixkanaka handitzea eta errepikatzeko botoi pertsonalizagarria esnatzeko esperientzia atsegina izateko. Erabiltzaile-interfazearekin, alarmak konfiguratzea ez da inoiz erraza izan. + +️ KRONOMETRO ZEHATZA: +Jarraitu zure jarduerei zehaztasunez Fossify erlojuaren kronometroaren funtzioa erabiliz. Neurtu denbora luzeagoak edo banakako itzuliak esfortzurik gabe. Zure itzuliak goranzko edo beheranzko ordenan ere ordena ditzakezu. + + TENPORIZATOREAREN FUNTZIONALITATEA: +Egon zure zereginen gainean Fossify erlojuaren tenporizadore-funtzio polifazetikoarekin. Pertsonalizatu dei-tonuen hobespenak, aldatu bibrazioak eta pausatu atzerako kontaketa zure beharretara egokitzeko. Sukalde-lanetako tarteak, ikasketa saioak kudeatzen edo atsedenaldi puntualak ziurtatzen ari zaren ala ez, Fossify erlojuak zehaztasun eta erraztasunarekin estali zaitu. + +🌈 ERLOUAREN TREPETA PERTSONALIZATZEKO EZAUGARRIEKIN: +Eraldatu zure hasierako pantaila Fossify erlojuaren erloju trepeta pertsonalizagarriarekin. Doitu testuaren kolorea, atzeko planoaren kolorea eta gardentasuna. Aukeratu erloju analogikoa edo digitala zure estilora egokitzeko eta erraz eskura ezazu orduko funtsezko informazioa begiratu batean. + +🎨 INTERFAZE ETA GAI PERTSONALIZAGARRIAK: +Gozatu esperientzia pertsonalizatua Fossify erlojuaren materialaren diseinuarekin eta gai iluneko aukerekin. Egokitu aplikazioa zure hobespenetara kolore eta gai pertsonalizatuekin, erabilgarritasuna hobetuz eta begien nekea murriztuz, batez ere argi gutxiko inguruneetan. + +🔒 PRIBATUTASUNA-LEHEN HURBILKETA: +Lasai egon zure pribatutasuna Fossify erlojuaren lineaz kanpoko funtzionamenduarekin babestuta dagoela. Bizi ezazu pribatutasun, segurtasun eta egonkortasun handiena funtzionaltasunari edo erosotasunari uko egin gabe. + +🌐 IRAGARKI GABE ETA ITURRI IREKIA: +Esan agur iragarki intrusiboei eta beharrezkoak ez diren baimenei. Fossify erlojua iragarkirik gabekoa da, guztiz kode irekikoa, eta zure denbora-esperientziaren kontrol osoa ematen dizu. + +Hobetu zure denbora kudeatzeko trebetasunak, optimizatu zure errutinak eta lehenetsi lo hobeago Fossify erlojuarekin. Deskargatu orain eta hartu zure denbora inoiz ez bezala kontrolatu. + +Arakatu Fossify aplikazio gehiago: https://www.fossify.org +Iturburu irekiko kodea: https://www.github.com/FossifyOrg +Sartu komunitatean Reddit-en: https://www.reddit.com/r/Fossify +Konektatu Telegram-en: https://t.me/Fossify diff --git a/fastlane/metadata/android/eu-ES/short_description.txt b/fastlane/metadata/android/eu-ES/short_description.txt new file mode 100644 index 00000000..7c499360 --- /dev/null +++ b/fastlane/metadata/android/eu-ES/short_description.txt @@ -0,0 +1 @@ +Erloju-aplikazio arina eta kode irekikoa, funtsezko ezaugarriak dituena. diff --git a/fastlane/metadata/android/eu-ES/title.txt b/fastlane/metadata/android/eu-ES/title.txt new file mode 100644 index 00000000..2a02e934 --- /dev/null +++ b/fastlane/metadata/android/eu-ES/title.txt @@ -0,0 +1 @@ +Fossify erlojua diff --git a/fastlane/metadata/android/fr-FR/changelogs/1.txt b/fastlane/metadata/android/fr-FR/changelogs/1.txt new file mode 100644 index 00000000..4d701553 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/1.txt @@ -0,0 +1 @@ +* Première parution. diff --git a/fastlane/metadata/android/fr-FR/changelogs/42.txt b/fastlane/metadata/android/fr-FR/changelogs/42.txt new file mode 100644 index 00000000..101f74b5 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/42.txt @@ -0,0 +1,2 @@ +* Correction de quelques problèmes liés aux alarmes + * Amélioration de l'interface utilisateur, de la traduction et de la stabilité diff --git a/fastlane/metadata/android/fr-FR/full_description.txt b/fastlane/metadata/android/fr-FR/full_description.txt new file mode 100644 index 00000000..214d9cc1 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/full_description.txt @@ -0,0 +1,32 @@ +Présentation de l'Horloge Fossify – l'ultime compagnon du temps, conçu pour enrichir vos routines quotidiennes et de promouvoir de meilleures habitudes de sommeil. Avec une multitude de fonctionnalités faite pour vos besoins, l'Horloge Fossify s'intègre dans votre vie, offrant un confort et une polyvalence inégalés. + +⌚ CHRONOMÈTRE MULTIFONCTION : +Découvrez la puissance de la gestion du temps polyvalente avec l'Horloge Fossify. Que ce soit pour servir de widget ou pour fonctionner comme un réveil et un chronomètre, cette application est l'outil idéal pour réguler vos activités quotidiennes et améliorer votre mode de vie global. + +⏰ ALARME RICHE EN FONCTIONNALITÉS : +Réveillez-vous en pleine forme grâce aux fonctions d'alarme complètes de l'Horloge Fossify. Réglez plusieurs alarmes avec des options telles que la sélection du jour, la vibration, les étiquettes personnalisées et la personnalisation de la sonnerie. Profitez d'une augmentation progressive du volume et d'un bouton de répétition personnalisable pour une expérience de réveil agréable. Grâce à une interface conviviale, il n'a jamais été aussi facile de régler des alarmes. + +⏱️ CHRONOMÈTRE PRATIQUE : +Enregistrez vos activités avec précision en utilisant la fonctionnalité chronomètre de l'Horloge Fossify. Mesurez de longues périodes ou des tours, sans efforts. Vous pouvez aussi trier vos tours dans l'ordre ascendant ou descendant. + +⏳ FONCTIONNALITÉ DE MINUTERIE PRÉCISE : +Restez au top de vos tâches grâce à la fonction polyvalente de minuterie de l'Horloge Fossify. Personnalisez vos sonneries, activez les vibrations et mettez en pause les minuteurs en fonction de vos besoins. Que vous chronométriez des intervalles de cuisson, gériez des sessions d'étude ou assuriez des pauses opportunes, l'Horloge Fossify vous couvre avec précision et facilité. + +🌈 WIDGET HORLOGE AVEC FONCTIONS PERSONNALISABLES : +Transformez votre écran d'accueil avec le widget horloge personnalisable de l'Horloge Fossify. Ajustez la couleur du texte, la couleur de fond et la transparence. Choisissez entre une horloge analogique ou numérique selon votre style et accédez facilement aux informations essentielles en un coup d'œil. + +🎨 INTERFACE ET THÈMES PERSONNALISABLES : +Profitez d'une expérience personnalisée grâce au design matériel et aux options de thème sombre de l'Horloge Fossify. Adaptez l'application à vos préférences avec des couleurs et des thèmes personnalisables, en améliorant la convivialité et en réduisant la fatigue oculaire, en particulier dans les environnements à faible luminosité. + +🔒 UNE APPROCHE AXÉE SUR LA PROTECTION DE LA VIE PRIVÉE : +Soyez rassuré en sachant que votre vie privée est protégée grâce au fonctionnement hors ligne de l'Horloge Fossify. Faites l'expérience d'une confidentialité, d'une sécurité et d'une stabilité maximales sans sacrifier fonctionnalités ou confort. + +🌐 SANS PUBS & OPEN-SOURCE : +Dites adieu aux publicités intrusives et aux autorisations inutiles. L'Horloge Fossify est sans publicité, entièrement open-source, et vous accorde un contrôle total sur votre chronomètre. + +Améliorez vos compétences dans la gestion du temps, optimisez vos routines et donnez la priorité à un meilleur sommeil avec l'Horloge Fossify. Téléchargez maintenant et prenez le contrôle de votre temps comme jamais auparavant. + +Explorez plus d'applications Fossify: https://www.fossify.org +Code Open-Source : https://www.github.com/FossifyOrg +Rejoignez la communauté sur Reddit : https://www.reddit.com/r/Fossify +Restez connecté sur Telegram : https://t.me/Fossify diff --git a/fastlane/metadata/android/fr-FR/short_description.txt b/fastlane/metadata/android/fr-FR/short_description.txt new file mode 100644 index 00000000..63d74e4b --- /dev/null +++ b/fastlane/metadata/android/fr-FR/short_description.txt @@ -0,0 +1 @@ +Application horloge pratique, légère et open source avec leurs fonctionnalités essentielles. diff --git a/fastlane/metadata/android/fr-FR/title.txt b/fastlane/metadata/android/fr-FR/title.txt new file mode 100644 index 00000000..63100bc3 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/title.txt @@ -0,0 +1 @@ +Fossify Horloge diff --git a/fastlane/metadata/android/ga/changelogs/1.txt b/fastlane/metadata/android/ga/changelogs/1.txt new file mode 100644 index 00000000..2889c5cc --- /dev/null +++ b/fastlane/metadata/android/ga/changelogs/1.txt @@ -0,0 +1 @@ +* Eisiúint tosaigh. diff --git a/fastlane/metadata/android/ga/full_description.txt b/fastlane/metadata/android/ga/full_description.txt new file mode 100644 index 00000000..4b442513 --- /dev/null +++ b/fastlane/metadata/android/ga/full_description.txt @@ -0,0 +1,32 @@ +Clog Fossify a thabhairt isteach – an compánach deiridh ama atá deartha chun do ghnáthaimh laethúla a fheabhsú agus nósanna codlata níos fearr a chur chun cinn. Agus an iliomad feidhmeanna curtha in oiriúint le do chuid riachtanas, comhtháthaíonn Fossify Clock gan uaim isteach i do shaol, ag tairiscint áise agus solúbthachta gan sárú. + +⌚ COINNEÁIL ILfheidhmeach: +Taithí a dhéanamh ar chumhacht na bainistíochta ama ildánach le Fossify Clog. Ó fónamh mar ghiuirléid cloig go feidhmiú mar chlog aláraim agus stopuaireadóir, is é an aip seo an uirlis chun do ghníomhaíochtaí laethúla a rialú agus chun do stíl mhaireachtála iomlán a fheabhsú. + +⏰ ALARM Saibhir Gné: +Múscail athnuachan le gnéithe cuimsitheacha aláraim Fossify Clock. Socraigh il-aláraim le roghanna amhail roghnú lae, scorán creathadh, lipéid shaincheaptha agus saincheapadh cloigíní. Bain sult as méadú de réir a chéile ar an toirt agus cnaipe snooze inoiriúnaithe le haghaidh eispéireas taitneamhach múscailte. Le comhéadan atá éasca le húsáid, ní raibh sé riamh níos éasca aláraim a shocrú. + +⏱️ STOPWATCH Áisiúil: +Rianaigh do ghníomhaíochtaí go beacht trí úsáid a bhaint as feidhm stopuaireadóir Fossify Clock. Déan tréimhsí níos faide nó lapaí aonair a thomhas gan stró. Is féidir leat freisin do laps a shórtáil in ord ardaitheach nó íslitheach. + +⏳ FEIDHMÍOCHT AMA BEACHT: +Fan ar bharr do thascanna leis an ngné lasc ama ildánach Fossify Clock. Saincheap roghanna glúnta, scoránaigh creathadh, agus sos comhaireamh síos chun freastal ar do chuid riachtanas. Cibé an bhfuil tú ag uainiú tréimhsí cócaireachta, ag bainistiú seisiúin staidéir, nó ag cinntiú sosanna tráthúla, tá Fossify Clock clúdaithe agat le cruinneas agus gan stró. + +🌈 Giuirléid CLOCK LE GNÉITHE CUSPÓIRÍ +Trasfhoirmigh do scáileán baile leis an ngiuirléid clog Inoiriúnaithe Fossify Clock. Coigeartaigh dath an téacs, dath cúlra, agus trédhearcacht. Roghnaigh idir chlog analógach nó clog digiteach a oireann le do stíl agus faigh sracfhéachaint ar eolas riachtanach ama. + +🎨 IDIRGHNÍOMHA AGUS TÉAMAÍ CUSTAIMÉADACHA: +Bain sult as taithí phearsantaithe le dearadh ábhar Fossify Clock agus roghanna téama dorcha. Cuir an aip in oiriúint le do chuid sainroghanna le dathanna agus téamaí inoiriúnaithe, ag cur le hinúsáidteacht agus ag laghdú brú súl, go háirithe i dtimpeallachtaí íseal-éadrom. + +🔒 PRÍOBHÁIDEACHT - AN CHÉAD CHUR CHUIGE: +Bí cinnte agus fios agat go bhfuil do phríobháideachas cosanta le hoibríocht as líne Fossify Clock. Taithí príobháideacht uasta, slándála, agus cobhsaíocht gan íobairt feidhmiúlacht nó áise. + +🌐 AD-SAOR IN AISCE & FOINSE OSCAILTE: +Slán le fógraí ionsáite agus ceadanna neamhriachtanacha. Tá Fossify Clock saor ó fhógraí, foinse oscailte go hiomlán, agus tugann sé smacht iomlán duit ar do thaithí ama ama. + +Uasghrádaigh do scileanna bainistíochta ama, barrfheabhsú do ghnáthaimh, agus tosaíocht a thabhairt do chodladh níos fearr le Fossify Clock. Íoslódáil anois agus bain smacht ar do chuid ama mar nach raibh riamh cheana. + +Déan tuilleadh aipeanna Fossify a iniúchadh: https://www.fossify.org +Cód Foinse Oscailte: https://www.github.com/FossifyOrg +Bí leis an bpobal ar Reddit: https://www.reddit.com/r/Fossify +Ceangail ar Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/ga/short_description.txt b/fastlane/metadata/android/ga/short_description.txt new file mode 100644 index 00000000..2534a1cd --- /dev/null +++ b/fastlane/metadata/android/ga/short_description.txt @@ -0,0 +1 @@ +Aip clog foinse oscailte áisiúil, éadrom le gnéithe riachtanacha. diff --git a/fastlane/metadata/android/ga/title.txt b/fastlane/metadata/android/ga/title.txt new file mode 100644 index 00000000..db0bc001 --- /dev/null +++ b/fastlane/metadata/android/ga/title.txt @@ -0,0 +1 @@ +Clog Fossify diff --git a/fastlane/metadata/android/gl-ES/changelogs/1.txt b/fastlane/metadata/android/gl-ES/changelogs/1.txt new file mode 100644 index 00000000..a1f6c8d3 --- /dev/null +++ b/fastlane/metadata/android/gl-ES/changelogs/1.txt @@ -0,0 +1 @@ +* Versión inicial. diff --git a/fastlane/metadata/android/id/changelogs/1.txt b/fastlane/metadata/android/id/changelogs/1.txt new file mode 100644 index 00000000..5727e141 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/1.txt @@ -0,0 +1 @@ +* Rilis awal. diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt new file mode 100644 index 00000000..a0d74ac8 --- /dev/null +++ b/fastlane/metadata/android/id/full_description.txt @@ -0,0 +1,32 @@ +Memperkenalkan Fossify Clock – pendamping penunjuk waktu terbaik yang dirancang untuk menyempurnakan rutinitas harian Anda dan meningkatkan kebiasaan tidur yang lebih baik. Dengan berbagai fungsi yang disesuaikan dengan kebutuhan Anda, Fossify Clock terintegrasi dengan mulus ke dalam kehidupan Anda, menawarkan kemudahan dan fleksibilitas yang tak tertandingi. + +⌚ PENCATATAN WAKTU MULTIFUNGSI: +Rasakan kekuatan manajemen waktu yang serbaguna dengan Fossify Clock. Dari berfungsi sebagai widget jam hingga berfungsi sebagai jam alarm dan stopwatch, aplikasi ini adalah alat yang tepat untuk mengatur aktivitas harian Anda dan meningkatkan gaya hidup Anda secara keseluruhan. + +⏰ ALARM YANG KAYA FITUR: +Bangun dengan segar dengan fitur alarm Fossify Clock yang komprehensif. Atur beberapa alarm dengan opsi seperti pemilihan hari, sakelar getar, label khusus, dan kustomisasi nada dering. Nikmati peningkatan volume secara bertahap dan tombol tunda yang dapat disesuaikan untuk pengalaman bangun yang menyenangkan. Dengan antarmuka yang ramah pengguna, mengatur alarm tidak pernah semudah ini. + +⏱️ STOPWATCH YANG NYAMAN: +Lacak aktivitas Anda dengan presisi menggunakan fungsi stopwatch Fossify Clock. Ukur periode yang lebih lama atau putaran individual dengan mudah. Anda juga dapat mengurutkan putaran Anda dalam urutan menaik atau menurun. + +⏳ FUNGSI PENGATUR WAKTU YANG TEPAT: +Tetaplah fokus pada tugas Anda dengan fitur pengatur waktu serbaguna Fossify Clock. Sesuaikan preferensi nada dering, alihkan getaran, dan jeda hitung mundur sesuai kebutuhan Anda. Baik Anda mengatur waktu memasak, mengatur sesi belajar, atau memastikan waktu istirahat tepat waktu, Fossify Clock siap membantu Anda dengan presisi dan mudah. + +🌈 WIDGET JAM DENGAN FITUR YANG DAPAT DISESUAIKAN: +Ubah layar beranda Anda dengan widget jam Fossify Clock yang dapat disesuaikan. Sesuaikan warna teks, warna latar belakang, dan transparansi. Pilih antara jam analog atau digital yang sesuai dengan gaya Anda dan akses informasi waktu penting dengan mudah dalam sekejap. + +🎨 ANTARMUKA DAN TEMA YANG DAPAT DISESUAIKAN: +Nikmati pengalaman yang dipersonalisasi dengan desain material dan opsi tema gelap Fossify Clock. Sesuaikan aplikasi dengan preferensi Anda dengan warna dan tema yang dapat disesuaikan, yang meningkatkan kegunaan dan mengurangi ketegangan mata, terutama di lingkungan dengan cahaya redup. + +🔒 PENDEKATAN YANG MENGUTAMAKAN PRIVASI: +Yakinlah bahwa privasi Anda terlindungi dengan operasi offline Fossify Clock. Rasakan privasi, keamanan, dan stabilitas maksimum tanpa mengorbankan fungsionalitas atau kenyamanan. + +🌐 BEBAS IKLAN & BERSUMBER TERBUKA: +Ucapkan selamat tinggal pada iklan yang mengganggu dan izin yang tidak perlu. Fossify Clock bebas iklan, sepenuhnya open-source, dan memberi Anda kendali penuh atas pengalaman pencatatan waktu Anda. + +Tingkatkan keterampilan manajemen waktu Anda, optimalkan rutinitas Anda, dan prioritaskan tidur yang lebih baik dengan Fossify Clock. Unduh sekarang dan kendalikan waktu Anda seperti yang belum pernah terjadi sebelumnya. + +Jelajahi lebih banyak aplikasi Fossify: https://www.fossify.org +Kode Sumber Terbuka: https://www.github.com/FossifyOrg +Bergabunglah dengan komunitas di Reddit: https://www.reddit.com/r/Fossify +Terhubung di Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/id/short_description.txt b/fastlane/metadata/android/id/short_description.txt index 00c6c4a7..499fccde 100644 --- a/fastlane/metadata/android/id/short_description.txt +++ b/fastlane/metadata/android/id/short_description.txt @@ -1 +1 @@ -Kombinasi widget jam yang indah, jam alarm, stopwatch, pengatur waktu +Aplikasi jam yang praktis, ringan, bersumber terbuka dengan fitur-fitur penting. diff --git a/fastlane/metadata/android/it-IT/changelogs/1.txt b/fastlane/metadata/android/it-IT/changelogs/1.txt new file mode 100644 index 00000000..b92e4cc4 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/1.txt @@ -0,0 +1 @@ +* Versione iniziale. diff --git a/fastlane/metadata/android/it-IT/full_description.txt b/fastlane/metadata/android/it-IT/full_description.txt new file mode 100644 index 00000000..4bdaf57e --- /dev/null +++ b/fastlane/metadata/android/it-IT/full_description.txt @@ -0,0 +1,32 @@ +Orologio Fossify è l'ultimo compagno per la misurazione dell'ora, progettato per migliorare le tue abitudini quotidiane e favorire un sonno migliore. Con una moltitudine di funzioni adatte alle tue esigenze, Orologio Fossify si integra perfettamente nella tua vita, offrendo una comodità e una versatilità senza pari. + +⌚ CRONOMETRAGGIO MULTIFUNZIONALE: +Sperimenta la potenza di una gestione versatile del tempo con Orologio Fossify. Dal widget dell'orologio alla sveglia e al cronometro, questa applicazione è lo strumento ideale per regolare le attività quotidiane e migliorare lo stile di vita generale. + +⏰ SVEGLIA RICCA DI FUNZIONI: +Svegliati rinfrescato con le funzioni di sveglia complete di Orologio Fossify. Imposta più sveglie con opzioni come la selezione del giorno, l'attivazione della vibrazione, le etichette personalizzate e la personalizzazione della suoneria. L'aumento graduale del volume e il pulsante snooze personalizzabile garantiscono una piacevole esperienza di risveglio. Grazie all'interfaccia intuitiva, impostare le sveglie non è mai stato così facile. + +⏱️ COMODO CRONOMETRO: +Traccia le tue attività con precisione grazie alla funzione cronometro di Orologio Fossify. Misura periodi più lunghi o singoli giri senza fatica. È anche possibile ordinare i giri in ordine crescente o decrescente. + +⏳ FUNZIONALITÀ DI TIMER PRECISO: +Rimani in cima alle tue attività con la versatile funzione timer di Orologio Fossify. Personalizza le preferenze della suoneria, attiva le vibrazioni e metti in pausa i conti alla rovescia in base alle tue esigenze. Che si tratti di cronometrare gli intervalli di cottura, di gestire le sessioni di studio o di garantire pause tempestive, Orologio Fossify ti copre con precisione e facilità. + +🌈 WIDGET OROLOGIO CON FUNZIONI PERSONALIZZABILI: +Trasforma la tua schermata iniziale con il widget orologio personalizzabile di Orologio Fossify. Regola il colore del testo, il colore dello sfondo e la trasparenza. Scegli tra orologio analogico o digitale per adattarlo al tuo stile e accedi facilmente alle informazioni essenziali sull'ora con un solo sguardo. + +🎨 INTERFACCIA E TEMI PERSONALIZZABILI: +Goditi un'esperienza personalizzata con il material design di Orologio Fossify e le opzioni dei temi scuri. Adatta l'app alle tue preferenze con colori e temi personalizzabili, migliorando l'usabilità e riducendo l'affaticamento degli occhi, soprattutto in ambienti con scarsa illuminazione. + +🔒 APPROCCIO ORIENTATO ALLA PRIVACY: +Sii certo che la tua privacy è protetta grazie al funzionamento offline di Orologio Fossify. Sperimenta la massima privacy, sicurezza e stabilità senza sacrificare la funzionalità o la convenienza. + +🌐 SENZA PUBBLICITÀ E OPEN-SOURCE: +Di' addio agli annunci invadenti e alle autorizzazioni non necessarie. Orologio Fossify è privo di pubblicità, completamente open-source e ti garantisce il controllo completo della tua esperienza di misurazione del tempo. + +Migliora le tue capacità di gestione del tempo, ottimizza le tue routine e dai priorità a un sonno migliore con Orologio Fossify. Scaricalo subito e prendiil controllo del tuo tempo come mai prima d'ora. + +Esplora altre applicazioni Fossify: https://www.fossify.org +Codice open-source: https://www.github.com/FossifyOrg +Unisciti alla comunità su Reddit: https://www.reddit.com/r/Fossify +Connettiti su Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/it-IT/short_description.txt b/fastlane/metadata/android/it-IT/short_description.txt new file mode 100644 index 00000000..61f41227 --- /dev/null +++ b/fastlane/metadata/android/it-IT/short_description.txt @@ -0,0 +1 @@ +Un'app per l'orologio pratica, leggera e open-source con funzioni essenziali. diff --git a/fastlane/metadata/android/it-IT/title.txt b/fastlane/metadata/android/it-IT/title.txt new file mode 100644 index 00000000..f9f19c48 --- /dev/null +++ b/fastlane/metadata/android/it-IT/title.txt @@ -0,0 +1 @@ +Orologio Fossify diff --git a/fastlane/metadata/android/ja-JP/changelogs/1.txt b/fastlane/metadata/android/ja-JP/changelogs/1.txt new file mode 100644 index 00000000..4910713f --- /dev/null +++ b/fastlane/metadata/android/ja-JP/changelogs/1.txt @@ -0,0 +1 @@ +* 初公開。 diff --git a/fastlane/metadata/android/ja-JP/title.txt b/fastlane/metadata/android/ja-JP/title.txt new file mode 100644 index 00000000..21c4323e --- /dev/null +++ b/fastlane/metadata/android/ja-JP/title.txt @@ -0,0 +1 @@ +Fossify時計 diff --git a/fastlane/metadata/android/nl-NL/short_description.txt b/fastlane/metadata/android/nl-NL/short_description.txt new file mode 100644 index 00000000..0ed67b3b --- /dev/null +++ b/fastlane/metadata/android/nl-NL/short_description.txt @@ -0,0 +1 @@ +Handige, lichtgewicht opensource klok met alle essentiële functies. diff --git a/fastlane/metadata/android/pl-PL/full_description.txt b/fastlane/metadata/android/pl-PL/full_description.txt new file mode 100644 index 00000000..73355635 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/full_description.txt @@ -0,0 +1,32 @@ +Przedstawiamy Fossify Clock – najlepszy towarzysz mierzący czas zaprojektowany w celu usprawnienia Twoich codziennych czynności i promowania lepszych nawyków związanych ze snem. Dzięki mnóstwu funkcji dostosowanych do Twoich potrzeb Fossify Clock bezproblemowo integruje się z Twoim życiem, oferując niezrównaną wygodę i wszechstronność. + +⌚ WIELOFUNKCYJNY POMIAR CZASU: +Doświadcz mocy wszechstronnego zarządzania czasem z Fossify Clock. Od bycia widżetem zegara po funkcjonowanie jako alarm i stoper aplikacja ta jest Twoim podstawowym narzędziem do regulowania codziennych aktywności i poprawy Twojego ogólnego stylu życia. + +⏰ BOGATY W FUNKCJE ALARM: +Obudź się wypoczęty(-a) dzięki kompleksowym funkcjom alarmu Fossify Clock. Ustaw wiele alarmów z opcjami takimi jak wybór dnia, przełączanie wibracji, niestandardowe etykiety i dostosowywanie dzwonka. Ciesz się stopniowym zwiększaniem głośności i konfigurowalnym przyciskiem drzemki, aby zapewnić przyjemne budzenie się. Dzięki przyjaznemu dla użytkownika interfejsowi ustawianie alarmów nigdy nie było prostsze. + +⏱️ WYGODNY STOPER: +Śledź swoje aktywności z precyzją, korzystając z funkcji stopera Fossify Clock. Bezproblemowo mierz dłuższe okresy lub pojedyncze okrążenia. Możesz także sortować swoje okrążenia w kolejności rosnącej lub malejącej. + +⏳ PRECYZYJNA FUNKCJA MINUTNIKA: +Bądź na bieżąco ze swoimi zadaniami dzięki wszechstronnej funkcji minutnika Fossify Clock. Dostosowuj preferencje dzwonka, przełączaj wibracje i wstrzymuj odliczanie, aby dopasować je do swoich potrzeb. Niezależnie od tego, czy odmierzasz czas gotowania, zarządzasz czasem uczenia się, czy zapewniasz sobie chwilowe przerwy, Fossify Clock zapewni Ci precyzję i łatwość. + +🌈 WIDŻET ZEGARA Z KONFIGUROWALNYMI FUNKCJAMI: +Zmień swój ekran główny za pomocą konfigurowalnego widżetu zegara Fossify Clock. Dostosuj kolor tekstu, kolor tła i przezroczystość. Wybierz między zegarem analogowym a cyfrowym, aby dopasować go do Twojego stylu i łatwo uzyskać dostęp do najważniejszych informacji o czasie w mgnieniu oka. + +🎨 KONFIGUROWALNY INTERFEJS I MOTYWY: +Ciesz się spersonalizowanym doświadczeniem Fossify Clock dzięki Material Design i opcjom ciemnego motywu. Dostosuj aplikację do swoich preferencji dzięki konfigurowalnym kolorom i motywom, ulepszając użyteczność i redukując zmęczenie oczu szczególnie w warunkach słabego oświetlenia. + +🔒 PRZEDE WSZYSTKIM PRYWATNOŚĆ: +Miej pewność, że Twoja prywatność jest chroniona, dzięki działaniu offline Fossify Clock. Doświadcz maksymalnej prywatności, bezpieczeństwa i stabilności bez poświęcania funkcjonalności i wygody. + +🌐 BEZ REKLAM I OTWARTOŹRÓDŁOWOŚĆ: +Pożegnaj natrętne reklamy i niepotrzebne uprawnienia. Fossify Clock jest wolny od reklam, w pełni otwartoźródłowy i zapewnia Ci pełną kontrolę nad doświadczeniem pomiaru czasu. + +Ulepsz swoje umiejętności zarządzania czasem, zoptymalizuj swoje rutyny i nadaj priorytet lepszemu snu z Fossify Clock. Pobierz teraz i przejmij kontrolę nad swoim czasem jak nigdy dotąd. + +Odkryj więcej aplikacji od Fossify: https://www.fossify.org +Kod źródłowy: https://www.github.com/FossifyOrg +Dołącz do społeczności na Reddicie: https://www.reddit.com/r/Fossify +Połącz się na Telegramie: https://t.me/Fossify diff --git a/fastlane/metadata/android/pl-PL/short_description.txt b/fastlane/metadata/android/pl-PL/short_description.txt new file mode 100644 index 00000000..eb0f6e2e --- /dev/null +++ b/fastlane/metadata/android/pl-PL/short_description.txt @@ -0,0 +1 @@ +Poręczna, lekka, otwartoźródłowa aplikacja zegara z niezbędnymi funkcjami diff --git a/fastlane/metadata/android/pl-PL/title.txt b/fastlane/metadata/android/pl-PL/title.txt new file mode 100644 index 00000000..16fe316b --- /dev/null +++ b/fastlane/metadata/android/pl-PL/title.txt @@ -0,0 +1 @@ +Fossify Clock diff --git a/fastlane/metadata/android/pt-BR/changelogs/1.txt b/fastlane/metadata/android/pt-BR/changelogs/1.txt new file mode 100644 index 00000000..de7e2be2 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/1.txt @@ -0,0 +1 @@ +* Versão inicial. diff --git a/fastlane/metadata/android/pt-BR/full_description.txt b/fastlane/metadata/android/pt-BR/full_description.txt new file mode 100644 index 00000000..db6878e7 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/full_description.txt @@ -0,0 +1,32 @@ +Introducindo o Relógio Fossify - o companheiro definito para gerencimento de tempo, para melhorar suas rotinas diárias e motivar hábitos de sono melhores. Com uma multitude de funções feitas com suas necessidades em mente, o Relógio Fossify integra diretamente à sua vida, oferecendo conveniência e versatilidade excepcionais. + +⌚ MULTIFUNCTIONAL TIMEKEEPING: +Experience the power of versatile time management with Fossify Clock. From serving as a clock widget to functioning as an alarm clock and stopwatch, this app is your go-to tool for regulating your daily activities and improving your overall lifestyle. + +⏰ FEATURE-RICH ALARM: +Wake up refreshed with Fossify Clock's comprehensive alarm features. Set multiple alarms with options like day selection, vibration toggle, custom labels and ringtone customization. Enjoy gradual volume increase and a customizable snooze button for a pleasant waking experience. With a user-friendly interface, setting up alarms has never been easier. + +⏱️ CONVENIENT STOPWATCH: +Track your activities with precision using Fossify Clock's stopwatch function. Measure longer periods or individual laps effortlessly. You can also sort your laps in ascending or descending order. + +⏳ PRECISE TIMER FUNCTIONALITY: +Stay on top of your tasks with Fossify Clock's versatile timer feature. Customize ringtone preferences, toggle vibrations, and pause countdowns to suit your needs. Whether you're timing cooking intervals, managing study sessions, or ensuring timely breaks, Fossify Clock has you covered with precision and ease. + +🌈 CLOCK WIDGET WITH CUSTOMIZABLE FEATURES: +Transform your home screen with Fossify Clock's customizable clock widget. Adjust text color, background color, and transparency. Choose between analog or digital clock to suit your style and easily access essential time information at a glance. + +🎨 CUSTOMIZABLE INTERFACE AND THEMES: +Enjoy a personalized experience with Fossify Clock's material design and dark theme options. Tailor the app to your preferences with customizable colors and themes, enhancing usability and reducing eye strain, especially in low-light environments. + +🔒 PRIVACY-FIRST APPROACH: +Rest assured knowing your privacy is protected with Fossify Clock's offline operation. Experience maximum privacy, security, and stability without sacrificing functionality or convenience. + +🌐 AD-FREE & OPEN-SOURCE: +Say goodbye to intrusive ads and unnecessary permissions. Fossify Clock is ad-free, fully open-source, and grants you complete control over your timekeeping experience. + +Upgrade your time management skills, optimize your routines, and prioritize better sleep with Fossify Clock. Download now and take control of your time like never before. + +Explore more Fossify apps: https://www.fossify.org +Open-Source Code: https://www.github.com/FossifyOrg +Join the community on Reddit: https://www.reddit.com/r/Fossify +Connect on Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/pt-BR/short_description.txt b/fastlane/metadata/android/pt-BR/short_description.txt new file mode 100644 index 00000000..86b90732 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/short_description.txt @@ -0,0 +1 @@ +Um app de relógio de código aberto, útil, leve e com funções essenciais. diff --git a/fastlane/metadata/android/pt-BR/title.txt b/fastlane/metadata/android/pt-BR/title.txt new file mode 100644 index 00000000..6e25b0b8 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/title.txt @@ -0,0 +1 @@ +Relógio Fossify diff --git a/fastlane/metadata/android/sv-SE/changelogs/1.txt b/fastlane/metadata/android/sv-SE/changelogs/1.txt new file mode 100644 index 00000000..d1b6e00d --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/1.txt @@ -0,0 +1 @@ +* Initial version. diff --git a/fastlane/metadata/android/sv-SE/short_description.txt b/fastlane/metadata/android/sv-SE/short_description.txt new file mode 100644 index 00000000..76e8de99 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/short_description.txt @@ -0,0 +1 @@ +Användbar och minimalistisk klockapp med öppen källkod. diff --git a/fastlane/metadata/android/sv-SE/title.txt b/fastlane/metadata/android/sv-SE/title.txt new file mode 100644 index 00000000..16fe316b --- /dev/null +++ b/fastlane/metadata/android/sv-SE/title.txt @@ -0,0 +1 @@ +Fossify Clock diff --git a/fastlane/metadata/android/tr-TR/changelogs/1.txt b/fastlane/metadata/android/tr-TR/changelogs/1.txt new file mode 100644 index 00000000..5ed2f491 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/changelogs/1.txt @@ -0,0 +1 @@ +* İlk sürüm. diff --git a/fastlane/metadata/android/tr-TR/full_description.txt b/fastlane/metadata/android/tr-TR/full_description.txt new file mode 100644 index 00000000..907617b7 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/full_description.txt @@ -0,0 +1,36 @@ +Fossify Clock ile tanışın - günlük rutinlerinizi geliştirmek ve daha iyi uyku alışkanlıklarını teşvik etmek için tasarlanmış nihai zaman tutma arkadaşı. İhtiyaçlarınıza göre uyarlanmış çok sayıda işlevle Fossify Saat, benzersiz bir rahatlık ve çok yönlülük sunarak hayatınıza sorunsuz bir şekilde entegre olur. + +⌚ ÇOK İŞLEVLİ ZAMAN YÖNETİMİ: +Fossify Saat ile çok yönlü zaman yönetiminin gücünü deneyimleyin. Bir saat bileşeni olarak hizmet vermekten çalar saat ve kronometre olarak işlev görmeye kadar, bu uygulama günlük aktivitelerinizi düzenlemek ve genel yaşam tarzınızı iyileştirmek için başvuracağınız iyi bir araç. + +⏰ ZENGİN ÖZELLİKLİ ALARM: +Fossify Saat’in kapsamlı alarm özellikleriyle tazelenmiş olarak uyanın. Gün seçimi, titreşim geçişi, özel etiketler ve zil sesi özelleştirme gibi seçeneklerle birden fazla alarm kurun. Keyifli bir uyanma deneyimi için kademeli ses artışının ve özelleştirilebilir bir erteleme düğmesinin keyfini çıkarın. Kullanıcı dostu bir arayüz ile alarm kurmak hiç bu kadar kolay olmamıştı. + +⏱️ KULLANIŞLI KRONOMETRE: +Fossify Saat’in kronometre fonksiyonunu kullanarak aktivitelerinizi hassas bir şekilde takip edin. Uzun süreleri veya bireysel turları zahmetsizce ölçün. Ayrıca turlarınızı artan veya azalan sırada sıralayabilirsiniz. + +⏳ HASSAS ZAMANLAYICI İŞLEVİ: +Fossify Saat’in çok yönlü zamanlayıcı özelliği ile görevlerinizin başında kalın. Zil sesi tercihlerini özelleştirin, titreşimleri değiştirin ve geri sayımları ihtiyaçlarınıza göre duraklatın. İster yemek pişirme aralıklarını zamanlıyor, ister çalışma seanslarını yönetiyor veya zamanında mola veriyor olun, Fossify Saat size hassasiyet ve kolaylık sağlar. + +🌈 ÖZELLEŞTİRİLEBİLİR ÖZELLİKLERE SAHİP BİR SAAT BİLEŞENİ: +Fossify Saat’in özelleştirilebilir saat bileşeni ile ana ekranınızı dönüştürün. Metin rengini, arka plan rengini ve şeffaflığı ayarlayın. Tarzınıza uygun analog veya dijital saat arasında seçim yapın ve bir bakışta önemli zaman bilgilerine kolayca erişin. + +🎨 ÖZELLEŞTİRİLEBİLİR ARAYÜZ VE TEMALAR: +Fossify Saat’in materyal tasarımı ve koyu tema seçenekleriyle kişiselleştirilmiş bir deneyimin keyfini çıkarın. Özelleştirilebilir renkler ve temalarla uygulamayı tercihlerinize göre uyarlayın, kullanılabilirliği artırın ve özellikle düşük ışıklı ortamlarda göz yorgunluğunu azaltın. + +🔒 GİZLİLİK ÖNCELİKLİ YAKLAŞIM: +Fossify Saat’in çevrimdışı çalışmasıyla gizliliğinizin korunduğunu bilerek içiniz rahat olsun. İşlevsellik veya rahatlıktan ödün vermeden maksimum gizlilik, güvenlik ve kararlılığı yaşayın. + +🌐 REKLAMSIZ VE AÇIK KAYNAK: +Müdahaleci reklamlara ve gereksiz izinlere elveda deyin. Fossify Saat reklamsızdır, tamamen açık kaynaklıdır ve zaman tutma deneyiminiz üzerinde size tam kontrol sağlar. + +Fossify Saat ile zaman yönetimi becerilerinizi geliştirin, rutinlerinizi optimize edin ve daha iyi uykuya öncelik verin. Hemen indirin ve zamanınızın kontrolünü daha önce hiç olmadığı gibi elinize alın. + +Daha fazla Fossify uygulaması keşfedin: +https://www.fossify.org +Açık Kaynak Kod: +https://www.github.com/FossifyOrg +Reddit'te topluluğa katılın: +https://www.reddit.com/r/Fossify +Telegram üzerinden bağlanın: +https://t.me/Fossify diff --git a/fastlane/metadata/android/tr-TR/short_description.txt b/fastlane/metadata/android/tr-TR/short_description.txt new file mode 100644 index 00000000..9d186a52 --- /dev/null +++ b/fastlane/metadata/android/tr-TR/short_description.txt @@ -0,0 +1 @@ +Temel özelliklere sahip kullanışlı, hafif, açık kaynaklı saat uygulaması. diff --git a/fastlane/metadata/android/tr-TR/title.txt b/fastlane/metadata/android/tr-TR/title.txt new file mode 100644 index 00000000..4f20c44d --- /dev/null +++ b/fastlane/metadata/android/tr-TR/title.txt @@ -0,0 +1 @@ +Fossify Saat diff --git a/fastlane/metadata/android/uk/changelogs/1.txt b/fastlane/metadata/android/uk/changelogs/1.txt new file mode 100644 index 00000000..96f3b04c --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/1.txt @@ -0,0 +1 @@ +* Початковий випуск. diff --git a/fastlane/metadata/android/uk/full_description.txt b/fastlane/metadata/android/uk/full_description.txt new file mode 100644 index 00000000..c0eb1b3c --- /dev/null +++ b/fastlane/metadata/android/uk/full_description.txt @@ -0,0 +1,32 @@ +Представляємо вам Fossify Годинник — ідеальний компаньйон для обліку часу, розроблений для покращення ваших щоденних рутинних справ та сприяння кращому сну. Завдяки безлічі функцій, пристосованих до ваших потреб, Fossify Годинник легко інтегрується у ваше життя, пропонуючи неперевершену зручність та універсальність. + +⌚БАГАТОФУНКЦІОНАЛЬНИЙ ОБЛІК: +Відчуйте силу багатофункціонального обліку часом з Fossify Годинник. Від віджету годинника до будильника та секундоміра — цей застосунок стане вашим незамінним помічником у регулюванні повсякденної діяльності та покращенні загального стилю життя. + +⏰ БАГАТОФУНКЦІОНАЛЬНИЙ БУДИЛЬНИК: +Прокидайтеся бадьорими завдяки широким можливостям будильника Fossify Годинник. Встановлюйте кілька будильників з такими параметрами, як вибір дня, перемикання вібрації, власні мітки та налаштування мелодії. Насолоджуйтесь поступовим збільшенням гучності та налаштовуваною кнопкою повтору для приємного пробудження. Завдяки зручному інтерфейсу налаштувати будильник ще ніколи не було так просто. + +⏱️ ЗРУЧНИЙ СЕКУНДОМІР: +Точно відстежуйте свою активність за допомогою функції секундоміра у Fossify Годинник. Вимірюйте довші періоди або окремі кола без особливих зусиль. Ви також можете сортувати свої кола в порядку зростання або спадання. + +⏳ ТОЧНА ФУНКЦІЯ ТАЙМЕРА: +Залишайтеся на вершині своїх завдань з універсальною функцією таймера Fossify Годинник. Налаштуйте налаштування мелодії дзвінка, перемикайте вібрацію та призупиняйте зворотний відлік відповідно до ваших потреб. Незалежно від того, чи ви встановлюєте час для приготування їжі, чи керуєте навчальними сесіями, чи забезпечуєте своєчасні перерви, Fossify Годинник забезпечить вас усім необхідним. + +🌈 ВІДЖЕТ ГОДИННИКА З ФУНКЦІЯМИ, ЩО НАЛАШТОВУЮТЬСЯ: +Перетворіть свій домашній екран за допомогою налаштовуваного віджету з Fossify Годинник. Налаштуйте колір тексту, фону та прозорість. Обирайте аналоговий або цифровий годинник відповідно до вашого стилю та легко отримуйте доступ до важливої інформації про час з першого погляду. + +🎨 ІНТЕРФЕЙС ТА ТЕМИ, ЩО НАЛАШТОВУЮТЬСЯ: +Насолоджуйтесь персоналізованим інтерфейсом Fossify Годинник з матеріальним дизайном та темними темами. Налаштуйте застосунок відповідно до своїх уподобань за допомогою кольорів та тем, що налаштовуються, покращуючи зручність використання та зменшуючи навантаження на очі, особливо в умовах низької освітленості. + +🔒 ПІДХІД, ОРІЄНТОВАНИЙ НА ПРИВАТНІСТЬ: +Будьте впевнені, знаючи, що ваша приватність захищена завдяки роботі Fossify Годинник в режимі автономному режимі. Відчуйте максимальну приватність, безпеку та стабільність без шкоди для функціональності та зручності. + +🌐 БЕЗ РЕКЛАМИ ТА З ВІДКРИТИМ ВИХІДНИМ КОДОМ: +Попрощайтеся з нав'язливою рекламою та непотрібними дозволами. Fossify Годинник не містить реклами, має повністю відкритий вихідний код і надає вам повний контроль над вашим часом. + +Вдосконалюйте свої навички тайм-менеджменту, оптимізуйте свої рутини та визначайте пріоритети для кращого сну з Fossify Годинник. Завантажуйте зараз і контролюйте свій час, як ніколи раніше. + +Дізнайтеся більше про застосунки Fossify: https://www.fossify.org +Відкритий код: https://www.github.com/FossifyOrg +Приєднуйтесь до спільноти на Reddit: https://www.reddit.com/r/Fossify +Приєднуйтесь в Telegram: https://t.me/Fossify diff --git a/fastlane/metadata/android/uk/short_description.txt b/fastlane/metadata/android/uk/short_description.txt new file mode 100644 index 00000000..2b2b34bf --- /dev/null +++ b/fastlane/metadata/android/uk/short_description.txt @@ -0,0 +1 @@ +Зручний, легкий, з відкритим кодом застосунок годинника з важливими функціями. diff --git a/fastlane/metadata/android/uk/title.txt b/fastlane/metadata/android/uk/title.txt new file mode 100644 index 00000000..c4090529 --- /dev/null +++ b/fastlane/metadata/android/uk/title.txt @@ -0,0 +1 @@ +Fossify Годинник diff --git a/fastlane/metadata/android/zh-CN/changelogs/1.txt b/fastlane/metadata/android/zh-CN/changelogs/1.txt new file mode 100644 index 00000000..f9ea6237 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/changelogs/1.txt @@ -0,0 +1 @@ +* 首次发布。 diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt new file mode 100644 index 00000000..1607c2a0 --- /dev/null +++ b/fastlane/metadata/android/zh-CN/full_description.txt @@ -0,0 +1,32 @@ +隆重推出 Fossify 时钟——终极计时伴侣,旨在改善您的日常生活,促进更好的睡眠习惯。Fossify 时钟根据您的需求量身定制了多种功能,无缝融入您的生活,提供无与伦比的便利性和多功能性。 + +⌚ 多功能计时: +使用 Fossify 时钟体验多功能时间管理的强大功能。从时钟微件到闹钟和秒表,这款应用是您调节日常活动和改善整体生活方式的首选工具。 + +⏰ 功能丰富的闹钟: +Fossify 时钟的全面闹钟功能让您醒来时神清气爽。通过日期选择、振动切换、自定义标签和铃声自定义等选项设置多个闹钟。享受逐渐增加的音量和可定制的贪睡按钮,以获得愉快的清醒体验。凭借用户友好的界面,设置闹钟从未如此简单。 + +⏱️ 方便的秒表: +使用 Fossify 时钟的秒表功能精确跟踪您的活动。轻松测量更长的时间或单独的圈数。您还可以按升序或降序对圈数进行排序。 + +⏳ 精确计时器功能: +使用 Fossify 时钟的多功能计时器功能,随时掌握您的任务。自定义铃声首选项、切换振动和暂停倒计时,以满足您的需求。无论您是在计时烹饪间隔、管理学习课程,还是确保及时休息,Fossify 时钟都能精准而轻松地为您服务。 + +🌈 具有可自定义功能的时钟微件: +使用 Fossify 时钟的可自定义时钟微件改变您的主屏幕。调整文本颜色、背景颜色和透明度。在模拟或数字时钟之间进行选择,以适应您的风格,并轻松访问重要的时间信息。 + +🎨 可自定义的界面和主题: +Fossify 时钟的 Material 设计和深色主题选项,为您带来个性化体验。使用可自定义的颜色和主题根据您的喜好定制应用,增强可用性并减少眼睛疲劳,尤其是在弱光环境中。 + +🔒 隐私第一的方法: +请放心,Fossify 时钟的离线操作会保护您的隐私。在不牺牲功能或便利性的情况下,体验最大的隐私、安全性和稳定性。 + +🌐 无广告和开源: +告别侵入性广告和不必要的权限。Fossify 时钟无广告,完全开源,让您完全控制自己的计时体验。 + +使用 Fossify 时钟提升您的时间管理技能,优化您的日常生活,并优先考虑更好的睡眠。立即下载,以前所未有的方式掌控您的时间。 + +探索更多 Fossify 应用:https://www.fossify.org +开源代码:https://www.github.com/FossifyOrg +加入 Reddit 社区:https://www.reddit.com/r/Fossify +在 Telegram 上联系:https://t.me/Fossify diff --git a/fastlane/metadata/android/zh-CN/short_description.txt b/fastlane/metadata/android/zh-CN/short_description.txt index d12f2774..ce4872c4 100644 --- a/fastlane/metadata/android/zh-CN/short_description.txt +++ b/fastlane/metadata/android/zh-CN/short_description.txt @@ -1 +1 @@ -华丽时钟小工具、闹钟、秒表、计时器的集合 +便捷、轻量的开源时钟应用,具有基本功能。 diff --git a/fastlane/metadata/android/zh-CN/title.txt b/fastlane/metadata/android/zh-CN/title.txt new file mode 100644 index 00000000..7bf23adf --- /dev/null +++ b/fastlane/metadata/android/zh-CN/title.txt @@ -0,0 +1 @@ +Fossify 时钟 diff --git a/fastlane/metadata/android/zh-TW/changelogs/1.txt b/fastlane/metadata/android/zh-TW/changelogs/1.txt new file mode 100644 index 00000000..2abfe4a1 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/1.txt @@ -0,0 +1 @@ +* 初始版本。 diff --git a/fastlane/metadata/android/zh-TW/short_description.txt b/fastlane/metadata/android/zh-TW/short_description.txt new file mode 100644 index 00000000..196ebab7 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/short_description.txt @@ -0,0 +1 @@ +一款輕巧、開源的時鐘應用程式,提供你所需的基本功能。 diff --git a/fastlane/metadata/android/zh-TW/title.txt b/fastlane/metadata/android/zh-TW/title.txt new file mode 100644 index 00000000..b8866a9b --- /dev/null +++ b/fastlane/metadata/android/zh-TW/title.txt @@ -0,0 +1 @@ +Fossify 時鐘 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 78118653..f81d08ae 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,11 @@ [versions] #jetbrains kotlin = "1.9.22" +kotlinxSerializationJson = "1.6.0" #KSP ksp = "1.9.22-1.0.17" +#Detekt +detekt = "1.23.3" #AndroidX androidx-constraintlayout = "2.1.4" androidx-lifecycle = "2.7.0" @@ -48,6 +51,8 @@ autofittextview = { module = "me.grantland:autofittextview", version.ref = "auto #EventBus eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbus" } #KotlinX +#Kotlin +kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } #NumberPicker numberpicker = { module = "io.github.ShawnLin013:number-picker", version.ref = "numberpicker" } @@ -72,4 +77,6 @@ lifecycle = [ [plugins] android = { id = "com.android.application", version.ref = "gradlePlugins-agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }