Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
4b971ac
Updated gradle plugin 8.5, kotlin 1.9.22, java v17, target SDK 34
Dimowner Jan 21, 2024
19c0316
Migrated to gradle.ktx, version catalogs and ksp.
Dimowner Jan 21, 2024
dd8cd4b
Added Room database for Records with unit test coverage.
Dimowner Jan 24, 2024
2fc8729
Added ability to mark records as moved to recycle bin.
Dimowner Jan 25, 2024
dccfed3
Added Compose to the app and some test screens made with compose.
Dimowner Jan 28, 2024
ef15cc5
merge with master
Dimowner Feb 8, 2024
632a050
Compose Record info screen and Settings scree UI only.
Dimowner Feb 17, 2024
3f74462
Added new app preferences implementation PrefsV2
Dimowner Feb 25, 2024
593330b
New Settings screen written with Kotlin + Compose.
Dimowner Mar 3, 2024
89bb893
Show Records count and total Records duration.
Dimowner Mar 7, 2024
ba21836
Dynamic Recording settings UI updates. Animated Settings screen updates.
Dimowner Mar 8, 2024
fa7c035
Records list screen UI in Compose
Dimowner Mar 9, 2024
3e62304
Added FileDataSource and functions to work with files. Added RecordsD…
Dimowner Mar 10, 2024
433ea03
Import record implementation. Home screen drop down menu. Multiple fi…
Dimowner Mar 16, 2024
2601f3f
Home screen UI, Record information improvements. Store record duratio…
Dimowner Mar 17, 2024
dfe6ac9
Records screen UI. Home screen Dialogs.
Dimowner Mar 27, 2024
1b0c6e8
Update Home screen when active record changed.
Dimowner Mar 31, 2024
b16f984
Records screen implemented context menu actions. Added Rename/Delete/…
Dimowner Apr 1, 2024
8b76d51
Added more queries to Room database. Added more unit tests to Room da…
Dimowner Apr 6, 2024
33af901
Sort by (date/name/duration) records functionality. Add record to boo…
Dimowner Apr 6, 2024
e95f250
Added Welcome and Deleted records screens in Compose.
Dimowner Apr 7, 2024
1e27693
Added Welcome setup settings screen. Cleanup.
Dimowner Apr 7, 2024
f101cfd
Update UI when record deleted or restored. Improvements.
Dimowner Apr 28, 2024
20ebe4a
Move RecordsViewModel outside of the RecordsScreen to fix layout Prev…
Dimowner Apr 28, 2024
5da050d
Move SettingsViewModel outside of the SettingsScreen and WelcomeSetup…
Dimowner Apr 28, 2024
8466042
Move ViewModels outside of the Screens to fix layout Preview and impr…
Dimowner Apr 28, 2024
d66be76
Make rename/move to recycle/restore from recycle/delete safer - added…
Dimowner May 10, 2024
30f8bff
Merge with master
Dimowner Oct 13, 2024
5f23efa
Updated libraries versions
Dimowner Oct 13, 2024
89e7712
Added WaveformComposeView which is Compose equivalent of WaveformViewNew
Dimowner Nov 6, 2024
8976698
Implemented active record playback with UI updates on HomeScreen
Dimowner Nov 10, 2024
47333a5
Compose Waveform: Animate to start after stop. Don't update waveform …
Dimowner Nov 16, 2024
c399fca
Import Record Decoding. Record playback panel in the records screen.
Dimowner Dec 1, 2024
789ffae
Use Legacy Slider. Show timeline in home screen and hide it in record…
Dimowner Dec 8, 2024
74da024
Playback Panel UI, interactions and animations. Compose waveform heig…
Dimowner Dec 14, 2024
d320cac
Improved Records play panel enter and exit animations. Fixed records …
Dimowner Dec 21, 2024
66c8bd3
Added empty screen logo. Added empty logo to empty list. Fixed TouchP…
Dimowner Feb 24, 2025
7027303
Ability to switch to new app version (V2) and back to the legacy vers…
Dimowner Jun 8, 2025
410a375
Updated target SDK to 36, minSdk to 24. Updated gradlew plugin. Updat…
Dimowner Oct 11, 2025
35bd353
Fix back navigation and dark status bar icons when status bar also dark.
Dimowner Oct 18, 2025
40d81b0
Added records Multi-Select feature that allows to share/download/move…
Dimowner Oct 20, 2025
6ed72d6
Added date headers to the records list. Some cleanup.
Dimowner Oct 25, 2025
47fa433
Update Recording panel. Simple recording. Some fixes and improvements…
Dimowner Nov 23, 2025
8192240
Waveform Max amplitude 32767. Auto remove outdated records from trash…
Dimowner Dec 21, 2025
4ae36af
Waveform test data cleanup. Move to recycle improvements for one and …
Dimowner Dec 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 0 additions & 117 deletions app/build.gradle

This file was deleted.

135 changes: 135 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.ksp)
alias(libs.plugins.hilt)
alias(libs.plugins.compose.compiler)
id("kotlin-parcelize")
}

android {
namespace = "com.dimowner.audiorecorder"
compileSdk = 36

defaultConfig {
applicationId = "com.dimowner.audiorecorder"
minSdk = 24
targetSdk = 36
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}

buildFeatures {
viewBinding = true
}

signingConfigs {
create("dev") {
storeFile = file("key/debug/debug.keystore")
storePassword = "android"
keyAlias = "androiddebugkey"
keyPassword = "android"
}
}

buildTypes {
getByName("release") {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android.txt"),
"proguard-rules.pro"
)
// firebaseCrashlytics {
// mappingFileUploadEnabled true
// }
}
getByName("debug") {
isMinifyEnabled = false
}
}

flavorDimensions += listOf("default")
productFlavors {
create("debugConfig") {
dimension = "default"
applicationId = "com.dimowner.audiorecorder.debug"
signingConfig = signingConfigs.getByName("dev")
}
create("releaseConfig") {
dimension = "default"
signingConfig = signingConfigs.getByName("dev")
applicationId = "com.dimowner.audiorecorder"
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
viewBinding = true
buildConfig = true
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
}
packaging {
resources.excludes.addAll(
listOf("META-INF/LICENSE.md", "META-INF/LICENSE-notice.md")
)
}
}

composeCompiler {
reportsDestination = layout.buildDirectory.dir("compose_compiler")
stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_config.conf")
}

dependencies {
ksp(libs.androidx.room.compiler)
ksp(libs.hilt.android.compiler)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.coroutines.android)
implementation(libs.timber)
implementation(libs.androidx.viewpager2)
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
implementation(libs.androidx.documentfile)
implementation(libs.hilt.android)
implementation(libs.exoplayer.core)
implementation(libs.exoplayer.ui)
implementation(libs.androidx.core.splashscreen)
implementation(libs.gson)

// Compose
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.constraintlayout.compose)
implementation(libs.androidx.compose.runtime)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.foundation)
implementation(libs.androidx.compose.foundation.layout)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.ui.viewbinding)
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.compose.runtime.livedata)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.navigation.compose)
implementation(libs.hilt.navigation.compose)

testImplementation(libs.junit)
testImplementation(libs.androidx.junit.ktx)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.mockk)
androidTestImplementation(libs.mockk)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2024 Dmytro Ponomarenko
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.dimowner.audiorecorder.v2.app

import android.content.Context
import android.content.res.Resources
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class AppExtensionsTest {

@Test
fun formatDuration_correctly_formats_duration() {
val resources: Resources = ApplicationProvider.getApplicationContext<Context?>().resources

val durationMillis = (365L * 24 * 60 * 60 + 24L * 60 * 60 + 60L * 60 + 60 + 1) * 1000
Assert.assertEquals("1year 1day 01h:01m:01s", formatDuration(resources, durationMillis))

val durationMillis2 = (365L * 24 * 60 * 60) * 1000
Assert.assertEquals("1year 00m:00s", formatDuration(resources, durationMillis2))

val durationMillis3 = (24L * 60 * 60 + 60L * 60 + 60 + 1) * 1000
Assert.assertEquals("1day 01h:01m:01s", formatDuration(resources, durationMillis3))

val durationMillis4 = (23L * 60 * 60 + 59 * 60 + 59) * 1000
Assert.assertEquals("23h:59m:59s", formatDuration(resources, durationMillis4))

val durationMillis5 = (10 * 365L * 24 * 60 * 60 + 125 * 24 * 60 * 60 + 23L * 60 * 60 + 59 * 60 + 59) * 1000
Assert.assertEquals("10years 125days 23h:59m:59s", formatDuration(resources, durationMillis5))
}

@Test
fun formatDuration_handles_zero_duration() {
// Example input: 0 milliseconds
val durationMillis = 0L

val resources: Resources = ApplicationProvider.getApplicationContext<Context?>().resources

val formattedDuration = formatDuration(resources, durationMillis)

Assert.assertEquals("00m:00s", formattedDuration)
}
}
Loading