Migrate to viewbinding and kotlin gradle scripts

- Replaced kotlinx sythetic with viewbinding
- Update build scripts to kotlin
- Intoduced version catalog, similar to Commons
- Updated kotlin from 1.7.10 to 1.9.0
- Updated Android Gradle Plugin to 8.1.0
This commit is contained in:
Ensar Sarajčić 2023-08-03 16:58:36 +02:00
parent a212b51e64
commit 89e76cc293
23 changed files with 462 additions and 353 deletions

View file

@ -1,74 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
android {
compileSdkVersion 34
defaultConfig {
applicationId "com.simplemobiletools.voicerecorder"
minSdkVersion 23
targetSdkVersion 34
versionCode 38
versionName "5.12.0"
setProperty("archivesBaseName", "voice-recorder")
vectorDrawables.useSupportLibrary = true
}
signingConfigs {
if (keystorePropertiesFile.exists()) {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
if (keystorePropertiesFile.exists()) {
signingConfig signingConfigs.release
}
}
}
flavorDimensions "variants"
productFlavors {
core {}
fdroid {}
prepaid {}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
lintOptions {
checkReleaseBuilds false
abortOnError false
}
}
dependencies {
implementation 'com.github.SimpleMobileTools:Simple-Commons:fad9b2cdb0'
implementation 'org.greenrobot:eventbus:3.3.1'
implementation 'com.github.Armen101:AudioRecordView:1.0.4'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.github.naman14:TAndroidLame:1.1'
implementation 'me.grantland:autofittextview:0.2.1'
}

100
app/build.gradle.kts Normal file
View file

@ -0,0 +1,100 @@
import java.io.FileInputStream
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.konan.properties.Properties
plugins {
alias(libs.plugins.android)
alias(libs.plugins.kotlinAndroid)
alias(libs.plugins.ksp)
}
val keystorePropertiesFile: File = rootProject.file("keystore.properties")
val keystoreProperties = Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
compileSdk = project.libs.versions.app.build.compileSDKVersion.get().toInt()
defaultConfig {
applicationId = libs.versions.app.version.appId.get()
minSdk = project.libs.versions.app.build.minimumSDK.get().toInt()
targetSdk = project.libs.versions.app.build.targetSDK.get().toInt()
versionName = project.libs.versions.app.version.versionName.get()
versionCode = project.libs.versions.app.version.versionCode.get().toInt()
setProperty("archivesBaseName", "voice-recorder")
vectorDrawables.useSupportLibrary = true
}
signingConfigs {
if (keystorePropertiesFile.exists()) {
register("release") {
keyAlias = keystoreProperties.getProperty("keyAlias")
keyPassword = keystoreProperties.getProperty("keyPassword")
storeFile = file(keystoreProperties.getProperty("storeFile"))
storePassword = keystoreProperties.getProperty("storePassword")
}
}
}
buildFeatures {
viewBinding = true
buildConfig = true
}
buildTypes {
debug {
applicationIdSuffix = ".debug"
}
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
if (keystorePropertiesFile.exists()) {
signingConfig = signingConfigs.getByName("release")
}
}
}
flavorDimensions.add("variants")
productFlavors {
register("core")
register("fdroid")
register("prepaid")
}
sourceSets {
getByName("main").java.srcDirs("src/main/kotlin")
}
compileOptions {
val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get().toString())
sourceCompatibility = currentJavaVersionFromLibs
targetCompatibility = currentJavaVersionFromLibs
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = project.libs.versions.app.build.kotlinJVMTarget.get()
}
namespace = libs.versions.app.version.appId.get()
lint {
checkReleaseBuilds = false
abortOnError = false
}
}
dependencies {
implementation(libs.simple.tools.commons)
implementation(libs.eventbus)
implementation(libs.audiorecordview)
implementation(libs.androidx.documentfile)
implementation(libs.androidx.swiperefreshlayout)
implementation(libs.androidx.constraintlayout)
implementation(libs.tandroidlame)
implementation(libs.autofittextview)
}

View file

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="com.simplemobiletools.voicerecorder"
android:installLocation="auto"> android:installLocation="auto">
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />

View file

@ -3,8 +3,8 @@ package com.simplemobiletools.voicerecorder.activities
import android.content.Intent import android.content.Intent
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
import com.simplemobiletools.commons.extensions.openNotificationSettings import com.simplemobiletools.commons.extensions.openNotificationSettings
import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.services.RecorderService import com.simplemobiletools.voicerecorder.services.RecorderService
import com.simplemobiletools.commons.R as CommonsR
class BackgroundRecordActivity : SimpleActivity() { class BackgroundRecordActivity : SimpleActivity() {
companion object { companion object {
@ -27,7 +27,7 @@ class BackgroundRecordActivity : SimpleActivity() {
} }
} }
} else { } else {
PermissionRequiredDialog(this, R.string.allow_notifications_voice_recorder, { openNotificationSettings() }) PermissionRequiredDialog(this, CommonsR.string.allow_notifications_voice_recorder, { openNotificationSettings() })
} }
} }
} }

View file

@ -12,30 +12,33 @@ import com.simplemobiletools.commons.models.FAQItem
import com.simplemobiletools.voicerecorder.BuildConfig import com.simplemobiletools.voicerecorder.BuildConfig
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.adapters.ViewPagerAdapter import com.simplemobiletools.voicerecorder.adapters.ViewPagerAdapter
import com.simplemobiletools.voicerecorder.databinding.ActivityMainBinding
import com.simplemobiletools.voicerecorder.extensions.checkRecycleBinItems import com.simplemobiletools.voicerecorder.extensions.checkRecycleBinItems
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.helpers.STOP_AMPLITUDE_UPDATE import com.simplemobiletools.voicerecorder.helpers.STOP_AMPLITUDE_UPDATE
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.services.RecorderService import com.simplemobiletools.voicerecorder.services.RecorderService
import kotlinx.android.synthetic.main.activity_main.*
import me.grantland.widget.AutofitHelper import me.grantland.widget.AutofitHelper
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import com.simplemobiletools.commons.R as CommonsR
class MainActivity : SimpleActivity() { class MainActivity : SimpleActivity() {
private var bus: EventBus? = null private var bus: EventBus? = null
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true isMaterialActivity = true
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
appLaunched(BuildConfig.APPLICATION_ID) appLaunched(BuildConfig.APPLICATION_ID)
setupOptionsMenu() setupOptionsMenu()
refreshMenuItems() refreshMenuItems()
updateMaterialActivityViews(main_coordinator, main_holder, useTransparentNavigation = false, useTopSearchMenu = true) updateMaterialActivityViews(binding.mainCoordinator, binding.mainHolder, useTransparentNavigation = false, useTopSearchMenu = true)
if (checkAppSideloading()) { if (checkAppSideloading()) {
return return
@ -49,7 +52,7 @@ class MainActivity : SimpleActivity() {
if (it) { if (it) {
tryInitVoiceRecorder() tryInitVoiceRecorder()
} else { } else {
toast(R.string.no_audio_permissions) toast(CommonsR.string.no_audio_permissions)
finish() finish()
} }
} }
@ -78,7 +81,7 @@ class MainActivity : SimpleActivity() {
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
config.lastUsedViewPagerPage = view_pager.currentItem config.lastUsedViewPagerPage = binding.viewPager.currentItem
} }
override fun onDestroy() { override fun onDestroy() {
@ -96,8 +99,8 @@ class MainActivity : SimpleActivity() {
} }
override fun onBackPressed() { override fun onBackPressed() {
if (main_menu.isSearchOpen) { if (binding.mainMenu.isSearchOpen) {
main_menu.closeSearch() binding.mainMenu.closeSearch()
} else if (isThirdPartyIntent()) { } else if (isThirdPartyIntent()) {
setResult(Activity.RESULT_CANCELED, null) setResult(Activity.RESULT_CANCELED, null)
super.onBackPressed() super.onBackPressed()
@ -107,27 +110,27 @@ class MainActivity : SimpleActivity() {
} }
private fun refreshMenuItems() { private fun refreshMenuItems() {
main_menu.getToolbar().menu.apply { binding.mainMenu.getToolbar().menu.apply {
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations) findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(CommonsR.bool.hide_google_relations)
} }
} }
private fun setupOptionsMenu() { private fun setupOptionsMenu() {
main_menu.getToolbar().inflateMenu(R.menu.menu) binding.mainMenu.getToolbar().inflateMenu(R.menu.menu)
main_menu.toggleHideOnScroll(false) binding.mainMenu.toggleHideOnScroll(false)
main_menu.setupMenu() binding.mainMenu.setupMenu()
main_menu.onSearchOpenListener = { binding.mainMenu.onSearchOpenListener = {
if (view_pager.currentItem == 0) { if (binding.viewPager.currentItem == 0) {
view_pager.currentItem = 1 binding.viewPager.currentItem = 1
} }
} }
main_menu.onSearchTextChangedListener = { text -> binding.mainMenu.onSearchTextChangedListener = { text ->
getPagerAdapter()?.searchTextChanged(text) getPagerAdapter()?.searchTextChanged(text)
} }
main_menu.getToolbar().setOnMenuItemClickListener { menuItem -> binding.mainMenu.getToolbar().setOnMenuItemClickListener { menuItem ->
when (menuItem.itemId) { when (menuItem.itemId) {
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
R.id.settings -> launchSettings() R.id.settings -> launchSettings()
@ -140,7 +143,7 @@ class MainActivity : SimpleActivity() {
private fun updateMenuColors() { private fun updateMenuColors() {
updateStatusbarColor(getProperBackgroundColor()) updateStatusbarColor(getProperBackgroundColor())
main_menu.updateColors() binding.mainMenu.updateColors()
} }
private fun tryInitVoiceRecorder() { private fun tryInitVoiceRecorder() {
@ -158,66 +161,66 @@ class MainActivity : SimpleActivity() {
} }
private fun setupViewPager() { private fun setupViewPager() {
main_tabs_holder.removeAllTabs() binding.mainTabsHolder.removeAllTabs()
var tabDrawables = arrayOf(R.drawable.ic_microphone_vector, R.drawable.ic_headset_vector) var tabDrawables = arrayOf(CommonsR.drawable.ic_microphone_vector, R.drawable.ic_headset_vector)
var tabLabels = arrayOf(R.string.recorder, R.string.player) var tabLabels = arrayOf(R.string.recorder, R.string.player)
if (config.useRecycleBin) { if (config.useRecycleBin) {
tabDrawables += R.drawable.ic_delete_vector tabDrawables += CommonsR.drawable.ic_delete_vector
tabLabels += R.string.recycle_bin tabLabels += CommonsR.string.recycle_bin
} }
tabDrawables.forEachIndexed { i, drawableId -> tabDrawables.forEachIndexed { i, drawableId ->
main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply { binding.mainTabsHolder.newTab().setCustomView(CommonsR.layout.bottom_tablayout_item).apply {
customView?.findViewById<ImageView>(R.id.tab_item_icon)?.setImageDrawable(getDrawable(drawableId)) customView?.findViewById<ImageView>(CommonsR.id.tab_item_icon)?.setImageDrawable(getDrawable(drawableId))
customView?.findViewById<TextView>(R.id.tab_item_label)?.setText(tabLabels[i]) customView?.findViewById<TextView>(CommonsR.id.tab_item_label)?.setText(tabLabels[i])
AutofitHelper.create(customView?.findViewById(R.id.tab_item_label)) AutofitHelper.create(customView?.findViewById(CommonsR.id.tab_item_label))
main_tabs_holder.addTab(this) binding.mainTabsHolder.addTab(this)
} }
} }
main_tabs_holder.onTabSelectionChanged( binding.mainTabsHolder.onTabSelectionChanged(
tabUnselectedAction = { tabUnselectedAction = {
updateBottomTabItemColors(it.customView, false) updateBottomTabItemColors(it.customView, false)
if (it.position == 1 || it.position == 2) { if (it.position == 1 || it.position == 2) {
main_menu.closeSearch() binding.mainMenu.closeSearch()
} }
}, },
tabSelectedAction = { tabSelectedAction = {
view_pager.currentItem = it.position binding.viewPager.currentItem = it.position
updateBottomTabItemColors(it.customView, true) updateBottomTabItemColors(it.customView, true)
} }
) )
view_pager.adapter = ViewPagerAdapter(this, config.useRecycleBin) binding.viewPager.adapter = ViewPagerAdapter(this, config.useRecycleBin)
view_pager.offscreenPageLimit = 2 binding.viewPager.offscreenPageLimit = 2
view_pager.onPageChangeListener { binding.viewPager.onPageChangeListener {
main_tabs_holder.getTabAt(it)?.select() binding.mainTabsHolder.getTabAt(it)?.select()
(view_pager.adapter as ViewPagerAdapter).finishActMode() (binding.viewPager.adapter as ViewPagerAdapter).finishActMode()
} }
if (isThirdPartyIntent()) { if (isThirdPartyIntent()) {
view_pager.currentItem = 0 binding.viewPager.currentItem = 0
} else { } else {
view_pager.currentItem = config.lastUsedViewPagerPage binding.viewPager.currentItem = config.lastUsedViewPagerPage
main_tabs_holder.getTabAt(config.lastUsedViewPagerPage)?.select() binding.mainTabsHolder.getTabAt(config.lastUsedViewPagerPage)?.select()
} }
} }
private fun setupTabColors() { private fun setupTabColors() {
val activeView = main_tabs_holder.getTabAt(view_pager.currentItem)?.customView val activeView = binding.mainTabsHolder.getTabAt(binding.viewPager.currentItem)?.customView
val inactiveView = main_tabs_holder.getTabAt(getInactiveTabIndex())?.customView val inactiveView = binding.mainTabsHolder.getTabAt(getInactiveTabIndex())?.customView
updateBottomTabItemColors(activeView, true) updateBottomTabItemColors(activeView, true)
updateBottomTabItemColors(inactiveView, false) updateBottomTabItemColors(inactiveView, false)
main_tabs_holder.getTabAt(view_pager.currentItem)?.select() binding.mainTabsHolder.getTabAt(binding.viewPager.currentItem)?.select()
val bottomBarColor = getBottomNavigationBackgroundColor() val bottomBarColor = getBottomNavigationBackgroundColor()
main_tabs_holder.setBackgroundColor(bottomBarColor) binding.mainTabsHolder.setBackgroundColor(bottomBarColor)
updateNavigationBarColor(bottomBarColor) updateNavigationBarColor(bottomBarColor)
} }
private fun getInactiveTabIndex() = if (view_pager.currentItem == 0) 1 else 0 private fun getInactiveTabIndex() = if (binding.viewPager.currentItem == 0) 1 else 0
private fun getPagerAdapter() = (view_pager.adapter as? ViewPagerAdapter) private fun getPagerAdapter() = (binding.viewPager.adapter as? ViewPagerAdapter)
private fun launchSettings() { private fun launchSettings() {
hideKeyboard() hideKeyboard()
@ -229,12 +232,12 @@ class MainActivity : SimpleActivity() {
val faqItems = arrayListOf( val faqItems = arrayListOf(
FAQItem(R.string.faq_1_title, R.string.faq_1_text), FAQItem(R.string.faq_1_title, R.string.faq_1_text),
FAQItem(R.string.faq_9_title_commons, R.string.faq_9_text_commons) FAQItem(CommonsR.string.faq_9_title_commons, CommonsR.string.faq_9_text_commons)
) )
if (!resources.getBoolean(R.bool.hide_google_relations)) { if (!resources.getBoolean(CommonsR.bool.hide_google_relations)) {
faqItems.add(FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons)) faqItems.add(FAQItem(CommonsR.string.faq_2_title_commons, CommonsR.string.faq_2_text_commons))
faqItems.add(FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons)) faqItems.add(FAQItem(CommonsR.string.faq_6_title_commons, CommonsR.string.faq_6_text_commons))
} }
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true) startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true)

View file

@ -8,6 +8,7 @@ import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.databinding.ActivitySettingsBinding
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.extensions.emptyTheRecycleBin import com.simplemobiletools.voicerecorder.extensions.emptyTheRecycleBin
import com.simplemobiletools.voicerecorder.extensions.getAllRecordings import com.simplemobiletools.voicerecorder.extensions.getAllRecordings
@ -16,26 +17,28 @@ import com.simplemobiletools.voicerecorder.helpers.EXTENSION_M4A
import com.simplemobiletools.voicerecorder.helpers.EXTENSION_MP3 import com.simplemobiletools.voicerecorder.helpers.EXTENSION_MP3
import com.simplemobiletools.voicerecorder.helpers.EXTENSION_OGG import com.simplemobiletools.voicerecorder.helpers.EXTENSION_OGG
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import kotlinx.android.synthetic.main.activity_settings.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import java.util.Locale import java.util.Locale
import kotlin.system.exitProcess import kotlin.system.exitProcess
import com.simplemobiletools.commons.R as CommonsR
class SettingsActivity : SimpleActivity() { class SettingsActivity : SimpleActivity() {
private var recycleBinContentSize = 0 private var recycleBinContentSize = 0
private lateinit var binding: ActivitySettingsBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true isMaterialActivity = true
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings) binding = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(binding.root)
updateMaterialActivityViews(settings_coordinator, settings_holder, useTransparentNavigation = true, useTopSearchMenu = false) updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
setupMaterialScrollListener(settings_nested_scrollview, settings_toolbar) setupMaterialScrollListener(binding.settingsNestedScrollview, binding.settingsToolbar)
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
setupToolbar(settings_toolbar, NavigationIcon.Arrow) setupToolbar(binding.settingsToolbar, NavigationIcon.Arrow)
setupPurchaseThankYou() setupPurchaseThankYou()
setupCustomizeColors() setupCustomizeColors()
@ -51,29 +54,29 @@ class SettingsActivity : SimpleActivity() {
setupRecordAfterLaunch() setupRecordAfterLaunch()
setupUseRecycleBin() setupUseRecycleBin()
setupEmptyRecycleBin() setupEmptyRecycleBin()
updateTextColors(settings_nested_scrollview) updateTextColors(binding.settingsNestedScrollview)
arrayOf(settings_color_customization_section_label, settings_general_settings_label, settings_recycle_bin_label).forEach { arrayOf(binding.settingsColorCustomizationLabel, binding.settingsGeneralSettingsLabel, binding.settingsRecycleBinLabel).forEach {
it.setTextColor(getProperPrimaryColor()) it.setTextColor(getProperPrimaryColor())
} }
} }
private fun setupPurchaseThankYou() { private fun setupPurchaseThankYou() {
settings_purchase_thank_you_holder.beGoneIf(isOrWasThankYouInstalled()) binding.settingsPurchaseThankYouHolder.beGoneIf(isOrWasThankYouInstalled())
settings_purchase_thank_you_holder.setOnClickListener { binding.settingsPurchaseThankYouHolder.setOnClickListener {
launchPurchaseThankYouIntent() launchPurchaseThankYouIntent()
} }
} }
private fun setupCustomizeColors() { private fun setupCustomizeColors() {
settings_color_customization_label.text = getCustomizeColorsString() binding.settingsColorCustomizationLabel.text = getCustomizeColorsString()
settings_color_customization_holder.setOnClickListener { binding.settingsColorCustomizationHolder.setOnClickListener {
handleCustomizeColorsClick() handleCustomizeColorsClick()
} }
} }
private fun setupCustomizeWidgetColors() { private fun setupCustomizeWidgetColors() {
settings_widget_color_customization_holder.setOnClickListener { binding.settingsWidgetColorCustomizationHolder.setOnClickListener {
Intent(this, WidgetRecordDisplayConfigureActivity::class.java).apply { Intent(this, WidgetRecordDisplayConfigureActivity::class.java).apply {
putExtra(IS_CUSTOMIZING_COLORS, true) putExtra(IS_CUSTOMIZING_COLORS, true)
startActivity(this) startActivity(this)
@ -82,41 +85,41 @@ class SettingsActivity : SimpleActivity() {
} }
private fun setupUseEnglish() { private fun setupUseEnglish() {
settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus()) binding.settingsUseEnglishHolder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus())
settings_use_english.isChecked = config.useEnglish binding.settingsUseEnglish.isChecked = config.useEnglish
settings_use_english_holder.setOnClickListener { binding.settingsUseEnglishHolder.setOnClickListener {
settings_use_english.toggle() binding.settingsUseEnglish.toggle()
config.useEnglish = settings_use_english.isChecked config.useEnglish = binding.settingsUseEnglish.isChecked
exitProcess(0) exitProcess(0)
} }
} }
private fun setupLanguage() { private fun setupLanguage() {
settings_language.text = Locale.getDefault().displayLanguage binding.settingsLanguage.text = Locale.getDefault().displayLanguage
settings_language_holder.beVisibleIf(isTiramisuPlus()) binding.settingsLanguageHolder.beVisibleIf(isTiramisuPlus())
settings_language_holder.setOnClickListener { binding.settingsLanguageHolder.setOnClickListener {
launchChangeAppLanguageIntent() launchChangeAppLanguageIntent()
} }
} }
private fun setupChangeDateTimeFormat() { private fun setupChangeDateTimeFormat() {
settings_change_date_time_format_holder.setOnClickListener { binding.settingsChangeDateTimeFormatHolder.setOnClickListener {
ChangeDateTimeFormatDialog(this) {} ChangeDateTimeFormatDialog(this) {}
} }
} }
private fun setupHideNotification() { private fun setupHideNotification() {
settings_hide_notification.isChecked = config.hideNotification binding.settingsHideNotification.isChecked = config.hideNotification
settings_hide_notification_holder.setOnClickListener { binding.settingsHideNotificationHolder.setOnClickListener {
settings_hide_notification.toggle() binding.settingsHideNotification.toggle()
config.hideNotification = settings_hide_notification.isChecked config.hideNotification = binding.settingsHideNotification.isChecked
} }
} }
private fun setupSaveRecordingsFolder() { private fun setupSaveRecordingsFolder() {
settings_save_recordings_label.text = addLockedLabelIfNeeded(R.string.save_recordings_in) binding.settingsSaveRecordingsLabel.text = addLockedLabelIfNeeded(R.string.save_recordings_in)
settings_save_recordings.text = humanizePath(config.saveRecordingsFolder) binding.settingsSaveRecordings.text = humanizePath(config.saveRecordingsFolder)
settings_save_recordings_holder.setOnClickListener { binding.settingsAudioSourceHolder.setOnClickListener {
if (isOrWasThankYouInstalled()) { if (isOrWasThankYouInstalled()) {
FilePickerDialog(this, config.saveRecordingsFolder, false, showFAB = true) { FilePickerDialog(this, config.saveRecordingsFolder, false, showFAB = true) {
val path = it val path = it
@ -131,7 +134,7 @@ class SettingsActivity : SimpleActivity() {
} }
config.saveRecordingsFolder = path config.saveRecordingsFolder = path
settings_save_recordings.text = humanizePath(config.saveRecordingsFolder) binding.settingsSaveRecordings.text = humanizePath(config.saveRecordingsFolder)
} }
} }
} }
@ -142,8 +145,8 @@ class SettingsActivity : SimpleActivity() {
} }
private fun setupExtension() { private fun setupExtension() {
settings_extension.text = config.getExtensionText() binding.settingsExtension.text = config.getExtensionText()
settings_extension_holder.setOnClickListener { binding.settingsExtensionHolder.setOnClickListener {
val items = arrayListOf( val items = arrayListOf(
RadioItem(EXTENSION_M4A, getString(R.string.m4a)), RadioItem(EXTENSION_M4A, getString(R.string.m4a)),
RadioItem(EXTENSION_MP3, getString(R.string.mp3)) RadioItem(EXTENSION_MP3, getString(R.string.mp3))
@ -155,19 +158,19 @@ class SettingsActivity : SimpleActivity() {
RadioGroupDialog(this@SettingsActivity, items, config.extension) { RadioGroupDialog(this@SettingsActivity, items, config.extension) {
config.extension = it as Int config.extension = it as Int
settings_extension.text = config.getExtensionText() binding.settingsExtension.text = config.getExtensionText()
} }
} }
} }
private fun setupBitrate() { private fun setupBitrate() {
settings_bitrate.text = getBitrateText(config.bitrate) binding.settingsBitrate.text = getBitrateText(config.bitrate)
settings_bitrate_holder.setOnClickListener { binding.settingsBitrateHolder.setOnClickListener {
val items = BITRATES.map { RadioItem(it, getBitrateText(it)) } as ArrayList val items = BITRATES.map { RadioItem(it, getBitrateText(it)) } as ArrayList
RadioGroupDialog(this@SettingsActivity, items, config.bitrate) { RadioGroupDialog(this@SettingsActivity, items, config.bitrate) {
config.bitrate = it as Int config.bitrate = it as Int
settings_bitrate.text = getBitrateText(config.bitrate) binding.settingsBitrate.text = getBitrateText(config.bitrate)
} }
} }
} }
@ -175,25 +178,25 @@ class SettingsActivity : SimpleActivity() {
private fun getBitrateText(value: Int): String = getString(R.string.bitrate_value).format(value / 1000) private fun getBitrateText(value: Int): String = getString(R.string.bitrate_value).format(value / 1000)
private fun setupRecordAfterLaunch() { private fun setupRecordAfterLaunch() {
settings_record_after_launch.isChecked = config.recordAfterLaunch binding.settingsRecordAfterLaunch.isChecked = config.recordAfterLaunch
settings_record_after_launch_holder.setOnClickListener { binding.settingsRecordAfterLaunchHolder.setOnClickListener {
settings_record_after_launch.toggle() binding.settingsRecordAfterLaunch.toggle()
config.recordAfterLaunch = settings_record_after_launch.isChecked config.recordAfterLaunch = binding.settingsRecordAfterLaunch.isChecked
} }
} }
private fun setupUseRecycleBin() { private fun setupUseRecycleBin() {
updateRecycleBinButtons() updateRecycleBinButtons()
settings_use_recycle_bin.isChecked = config.useRecycleBin binding.settingsUseRecycleBin.isChecked = config.useRecycleBin
settings_use_recycle_bin_holder.setOnClickListener { binding.settingsUseRecycleBinHolder.setOnClickListener {
settings_use_recycle_bin.toggle() binding.settingsUseRecycleBin.toggle()
config.useRecycleBin = settings_use_recycle_bin.isChecked config.useRecycleBin = binding.settingsUseRecycleBin.isChecked
updateRecycleBinButtons() updateRecycleBinButtons()
} }
} }
private fun updateRecycleBinButtons() { private fun updateRecycleBinButtons() {
settings_empty_recycle_bin_holder.beVisibleIf(config.useRecycleBin) binding.settingsEmptyRecycleBinHolder.beVisibleIf(config.useRecycleBin)
} }
private fun setupEmptyRecycleBin() { private fun setupEmptyRecycleBin() {
@ -206,18 +209,18 @@ class SettingsActivity : SimpleActivity() {
} }
runOnUiThread { runOnUiThread {
settings_empty_recycle_bin_size.text = recycleBinContentSize.formatSize() binding.settingsEmptyRecycleBinSize.text = recycleBinContentSize.formatSize()
} }
} }
settings_empty_recycle_bin_holder.setOnClickListener { binding.settingsEmptyRecycleBinHolder.setOnClickListener {
if (recycleBinContentSize == 0) { if (recycleBinContentSize == 0) {
toast(R.string.recycle_bin_empty) toast(CommonsR.string.recycle_bin_empty)
} else { } else {
ConfirmationDialog(this, "", R.string.empty_recycle_bin_confirmation, R.string.yes, R.string.no) { ConfirmationDialog(this, "", CommonsR.string.empty_recycle_bin_confirmation, CommonsR.string.yes, CommonsR.string.no) {
emptyTheRecycleBin() emptyTheRecycleBin()
recycleBinContentSize = 0 recycleBinContentSize = 0
settings_empty_recycle_bin_size.text = 0.formatSize() binding.settingsEmptyRecycleBinSize.text = 0.formatSize()
EventBus.getDefault().post(Events.RecordingTrashUpdated()) EventBus.getDefault().post(Events.RecordingTrashUpdated())
} }
} }
@ -225,13 +228,13 @@ class SettingsActivity : SimpleActivity() {
} }
private fun setupAudioSource() { private fun setupAudioSource() {
settings_audio_source.text = config.getAudioSourceText(config.audioSource) binding.settingsAudioSource.text = config.getAudioSourceText(config.audioSource)
settings_audio_source_holder.setOnClickListener { binding.settingsAudioSourceHolder.setOnClickListener {
val items = getAudioSources().map { RadioItem(it, config.getAudioSourceText(it)) } as ArrayList val items = getAudioSources().map { RadioItem(it, config.getAudioSourceText(it)) } as ArrayList
RadioGroupDialog(this@SettingsActivity, items, config.audioSource) { RadioGroupDialog(this@SettingsActivity, items, config.audioSource) {
config.audioSource = it as Int config.audioSource = it as Int
settings_audio_source.text = config.getAudioSourceText(config.audioSource) binding.settingsAudioSource.text = config.getAudioSourceText(config.audioSource)
} }
} }
} }

View file

@ -12,9 +12,10 @@ import com.simplemobiletools.commons.dialogs.FeatureLockedDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.databinding.WidgetRecordDisplayConfigBinding
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.helpers.MyWidgetRecordDisplayProvider import com.simplemobiletools.voicerecorder.helpers.MyWidgetRecordDisplayProvider
import kotlinx.android.synthetic.main.widget_record_display_config.* import com.simplemobiletools.commons.R as CommonsR
class WidgetRecordDisplayConfigureActivity : SimpleActivity() { class WidgetRecordDisplayConfigureActivity : SimpleActivity() {
private var mWidgetAlpha = 0f private var mWidgetAlpha = 0f
@ -22,12 +23,14 @@ class WidgetRecordDisplayConfigureActivity : SimpleActivity() {
private var mWidgetColor = 0 private var mWidgetColor = 0
private var mWidgetColorWithoutTransparency = 0 private var mWidgetColorWithoutTransparency = 0
private var mFeatureLockedDialog: FeatureLockedDialog? = null private var mFeatureLockedDialog: FeatureLockedDialog? = null
private lateinit var binding: WidgetRecordDisplayConfigBinding
public override fun onCreate(savedInstanceState: Bundle?) { public override fun onCreate(savedInstanceState: Bundle?) {
useDynamicTheme = false useDynamicTheme = false
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setResult(Activity.RESULT_CANCELED) setResult(Activity.RESULT_CANCELED)
setContentView(R.layout.widget_record_display_config) binding = WidgetRecordDisplayConfigBinding.inflate(layoutInflater)
setContentView(binding.root)
initVariables() initVariables()
val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false
@ -37,11 +40,11 @@ class WidgetRecordDisplayConfigureActivity : SimpleActivity() {
finish() finish()
} }
config_save.setOnClickListener { saveConfig() } binding.configSave.setOnClickListener { saveConfig() }
config_widget_color.setOnClickListener { pickBackgroundColor() } binding.configWidgetColor.setOnClickListener { pickBackgroundColor() }
val primaryColor = getProperPrimaryColor() val primaryColor = getProperPrimaryColor()
config_widget_seekbar.setColors(getProperTextColor(), primaryColor, primaryColor) binding.configWidgetSeekbar.setColors(getProperTextColor(), primaryColor, primaryColor)
if (!isCustomizingColors && !isOrWasThankYouInstalled()) { if (!isCustomizingColors && !isOrWasThankYouInstalled()) {
mFeatureLockedDialog = FeatureLockedDialog(this) { mFeatureLockedDialog = FeatureLockedDialog(this) {
@ -51,8 +54,8 @@ class WidgetRecordDisplayConfigureActivity : SimpleActivity() {
} }
} }
config_save.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor()) binding.configSave.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
config_save.setTextColor(getProperPrimaryColor().getContrastColor()) binding.configSave.setTextColor(getProperPrimaryColor().getContrastColor())
} }
override fun onResume() { override fun onResume() {
@ -67,14 +70,14 @@ class WidgetRecordDisplayConfigureActivity : SimpleActivity() {
private fun initVariables() { private fun initVariables() {
mWidgetColor = config.widgetBgColor mWidgetColor = config.widgetBgColor
if (mWidgetColor == resources.getColor(R.color.default_widget_bg_color) && config.isUsingSystemTheme) { if (mWidgetColor == resources.getColor(R.color.default_widget_bg_color) && config.isUsingSystemTheme) {
mWidgetColor = resources.getColor(R.color.you_primary_color, theme) mWidgetColor = resources.getColor(CommonsR.color.you_primary_color, theme)
} }
mWidgetAlpha = Color.alpha(mWidgetColor) / 255.toFloat() mWidgetAlpha = Color.alpha(mWidgetColor) / 255.toFloat()
mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor)) mWidgetColorWithoutTransparency = Color.rgb(Color.red(mWidgetColor), Color.green(mWidgetColor), Color.blue(mWidgetColor))
config_widget_seekbar.setOnSeekBarChangeListener(seekbarChangeListener) binding.configWidgetSeekbar.setOnSeekBarChangeListener(seekbarChangeListener)
config_widget_seekbar.progress = (mWidgetAlpha * 100).toInt() binding.configWidgetSeekbar.progress = (mWidgetAlpha * 100).toInt()
updateColors() updateColors()
} }
@ -107,8 +110,8 @@ class WidgetRecordDisplayConfigureActivity : SimpleActivity() {
private fun updateColors() { private fun updateColors() {
mWidgetColor = mWidgetColorWithoutTransparency.adjustAlpha(mWidgetAlpha) mWidgetColor = mWidgetColorWithoutTransparency.adjustAlpha(mWidgetAlpha)
config_widget_color.setFillWithStroke(mWidgetColor, mWidgetColor) binding.configWidgetColor.setFillWithStroke(mWidgetColor, mWidgetColor)
config_image.background.mutate().applyColorFilter(mWidgetColor) binding.configImage.background.mutate().applyColorFilter(mWidgetColor)
} }
private val seekbarChangeListener = object : SeekBar.OnSeekBarChangeListener { private val seekbarChangeListener = object : SeekBar.OnSeekBarChangeListener {

View file

@ -12,6 +12,7 @@ import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.voicerecorder.BuildConfig import com.simplemobiletools.voicerecorder.BuildConfig
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.activities.SimpleActivity import com.simplemobiletools.voicerecorder.activities.SimpleActivity
import com.simplemobiletools.voicerecorder.databinding.ItemRecordingBinding
import com.simplemobiletools.voicerecorder.dialogs.DeleteConfirmationDialog import com.simplemobiletools.voicerecorder.dialogs.DeleteConfirmationDialog
import com.simplemobiletools.voicerecorder.dialogs.RenameRecordingDialog import com.simplemobiletools.voicerecorder.dialogs.RenameRecordingDialog
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
@ -21,8 +22,8 @@ import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri
import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.models.Recording import com.simplemobiletools.voicerecorder.models.Recording
import kotlinx.android.synthetic.main.item_recording.view.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import com.simplemobiletools.commons.R as CommonsR
class RecordingsAdapter( class RecordingsAdapter(
activity: SimpleActivity, activity: SimpleActivity,
@ -74,7 +75,9 @@ class RecordingsAdapter(
override fun onActionModeDestroyed() {} override fun onActionModeDestroyed() {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_recording, parent) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return createViewHolder(ItemRecordingBinding.inflate(layoutInflater, parent, false).root)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val recording = recordings[position] val recording = recordings[position]
@ -136,7 +139,7 @@ class RecordingsAdapter(
} }
val baseString = if (activity.config.useRecycleBin) { val baseString = if (activity.config.useRecycleBin) {
R.string.move_to_recycle_bin_confirmation CommonsR.string.move_to_recycle_bin_confirmation
} else { } else {
R.string.delete_recordings_confirmation R.string.delete_recordings_confirmation
} }
@ -215,30 +218,30 @@ class RecordingsAdapter(
private fun getSelectedItems() = recordings.filter { selectedKeys.contains(it.id) } as ArrayList<Recording> private fun getSelectedItems() = recordings.filter { selectedKeys.contains(it.id) } as ArrayList<Recording>
private fun setupView(view: View, recording: Recording) { private fun setupView(view: View, recording: Recording) {
view.apply { ItemRecordingBinding.bind(view).apply {
setupViewBackground(activity) root.setupViewBackground(activity)
recording_frame?.isSelected = selectedKeys.contains(recording.id) recordingFrame.isSelected = selectedKeys.contains(recording.id)
arrayListOf<TextView>(recording_title, recording_date, recording_duration, recording_size).forEach { arrayListOf<TextView>(recordingTitle, recordingDate, recordingDuration, recordingSize).forEach {
it.setTextColor(textColor) it.setTextColor(textColor)
} }
if (recording.id == currRecordingId) { if (recording.id == currRecordingId) {
recording_title.setTextColor(context.getProperPrimaryColor()) recordingTitle.setTextColor(root.context.getProperPrimaryColor())
} }
recording_title.text = recording.title recordingTitle.text = recording.title
recording_date.text = recording.timestamp.formatDate(context) recordingDate.text = recording.timestamp.formatDate(root.context)
recording_duration.text = recording.duration.getFormattedDuration() recordingDuration.text = recording.duration.getFormattedDuration()
recording_size.text = recording.size.formatSize() recordingSize.text = recording.size.formatSize()
overflow_menu_icon.drawable.apply { overflowMenuIcon.drawable.apply {
mutate() mutate()
setTint(activity.getProperTextColor()) setTint(activity.getProperTextColor())
} }
overflow_menu_icon.setOnClickListener { overflowMenuIcon.setOnClickListener {
showPopupMenu(overflow_menu_anchor, recording) showPopupMenu(overflowMenuAnchor, recording)
} }
} }
} }

View file

@ -11,13 +11,14 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.views.MyRecyclerView import com.simplemobiletools.commons.views.MyRecyclerView
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.activities.SimpleActivity import com.simplemobiletools.voicerecorder.activities.SimpleActivity
import com.simplemobiletools.voicerecorder.databinding.ItemRecordingBinding
import com.simplemobiletools.voicerecorder.extensions.deleteRecordings import com.simplemobiletools.voicerecorder.extensions.deleteRecordings
import com.simplemobiletools.voicerecorder.extensions.restoreRecordings import com.simplemobiletools.voicerecorder.extensions.restoreRecordings
import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.models.Recording import com.simplemobiletools.voicerecorder.models.Recording
import kotlinx.android.synthetic.main.item_recording.view.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import com.simplemobiletools.commons.R as CommonsR
class TrashAdapter( class TrashAdapter(
activity: SimpleActivity, activity: SimpleActivity,
@ -59,7 +60,9 @@ class TrashAdapter(
override fun onActionModeDestroyed() {} override fun onActionModeDestroyed() {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_recording, parent) override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return createViewHolder(ItemRecordingBinding.inflate(layoutInflater, parent, false).root)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val recording = recordings[position] val recording = recordings[position]
@ -147,26 +150,26 @@ class TrashAdapter(
private fun getSelectedItems() = recordings.filter { selectedKeys.contains(it.id) } as ArrayList<Recording> private fun getSelectedItems() = recordings.filter { selectedKeys.contains(it.id) } as ArrayList<Recording>
private fun setupView(view: View, recording: Recording) { private fun setupView(view: View, recording: Recording) {
view.apply { ItemRecordingBinding.bind(view).apply {
setupViewBackground(activity) root.setupViewBackground(activity)
recording_frame?.isSelected = selectedKeys.contains(recording.id) recordingFrame.isSelected = selectedKeys.contains(recording.id)
arrayListOf<TextView>(recording_title, recording_date, recording_duration, recording_size).forEach { arrayListOf<TextView>(recordingTitle, recordingDate, recordingDuration, recordingSize).forEach {
it.setTextColor(textColor) it.setTextColor(textColor)
} }
recording_title.text = recording.title recordingTitle.text = recording.title
recording_date.text = recording.timestamp.formatDate(context) recordingDate.text = recording.timestamp.formatDate(root.context)
recording_duration.text = recording.duration.getFormattedDuration() recordingDuration.text = recording.duration.getFormattedDuration()
recording_size.text = recording.size.formatSize() recordingSize.text = recording.size.formatSize()
overflow_menu_icon.drawable.apply { overflowMenuIcon.drawable.apply {
mutate() mutate()
setTint(activity.getProperTextColor()) setTint(activity.getProperTextColor())
} }
overflow_menu_icon.setOnClickListener { overflowMenuIcon.setOnClickListener {
showPopupMenu(overflow_menu_anchor, recording) showPopupMenu(overflowMenuAnchor, recording)
} }
} }
} }
@ -186,7 +189,7 @@ class TrashAdapter(
PopupMenu(contextTheme, view, Gravity.END).apply { PopupMenu(contextTheme, view, Gravity.END).apply {
inflate(getActionMenuId()) inflate(getActionMenuId())
menu.findItem(R.id.cab_select_all).isVisible = false menu.findItem(R.id.cab_select_all).isVisible = false
menu.findItem(R.id.cab_restore).title = resources.getString(R.string.restore_this_file) menu.findItem(R.id.cab_restore).title = resources.getString(CommonsR.string.restore_this_file)
setOnMenuItemClickListener { item -> setOnMenuItemClickListener { item ->
val recordingId = recording.id val recordingId = recording.id
when (item.itemId) { when (item.itemId) {

View file

@ -53,7 +53,7 @@ class ViewPagerAdapter(private val activity: SimpleActivity, val showRecycleBin:
} }
fun finishActMode() { fun finishActMode() {
(mFragments[1] as? PlayerFragment)?.finishActMode() (mFragments[1] as? PlayerFragment)?.finishActMode()
if (showRecycleBin) { if (showRecycleBin) {
(mFragments[2] as? TrashFragment)?.finishActMode() (mFragments[2] as? TrashFragment)?.finishActMode()
} }

View file

@ -5,9 +5,8 @@ import androidx.appcompat.app.AlertDialog
import com.simplemobiletools.commons.extensions.beGoneIf import com.simplemobiletools.commons.extensions.beGoneIf
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
import com.simplemobiletools.commons.extensions.setupDialogStuff import com.simplemobiletools.commons.extensions.setupDialogStuff
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.databinding.DialogDeleteConfirmationBinding
import kotlinx.android.synthetic.main.dialog_delete_confirmation.view.delete_remember_title import com.simplemobiletools.commons.R as CommonsR
import kotlinx.android.synthetic.main.dialog_delete_confirmation.view.skip_the_recycle_bin_checkbox
class DeleteConfirmationDialog( class DeleteConfirmationDialog(
private val activity: Activity, private val activity: Activity,
@ -17,14 +16,15 @@ class DeleteConfirmationDialog(
) { ) {
private var dialog: AlertDialog? = null private var dialog: AlertDialog? = null
val view = activity.layoutInflater.inflate(R.layout.dialog_delete_confirmation, null)!! val binding = DialogDeleteConfirmationBinding.inflate(activity.layoutInflater)
val view = binding.root
init { init {
view.delete_remember_title.text = message binding.deleteRememberTitle.text = message
view.skip_the_recycle_bin_checkbox.beGoneIf(!showSkipRecycleBinOption) binding.skipTheRecycleBinCheckbox.beGoneIf(!showSkipRecycleBinOption)
activity.getAlertDialogBuilder() activity.getAlertDialogBuilder()
.setPositiveButton(R.string.yes) { _, _ -> dialogConfirmed() } .setPositiveButton(CommonsR.string.yes) { _, _ -> dialogConfirmed() }
.setNegativeButton(R.string.no, null) .setNegativeButton(CommonsR.string.no, null)
.apply { .apply {
activity.setupDialogStuff(view, this) { alertDialog -> activity.setupDialogStuff(view, this) { alertDialog ->
dialog = alertDialog dialog = alertDialog
@ -34,6 +34,6 @@ class DeleteConfirmationDialog(
private fun dialogConfirmed() { private fun dialogConfirmed() {
dialog?.dismiss() dialog?.dismiss()
callback(view.skip_the_recycle_bin_checkbox.isChecked) callback(binding.skipTheRecycleBinCheckbox.isChecked)
} }
} }

View file

@ -7,36 +7,37 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.commons.helpers.isRPlus import com.simplemobiletools.commons.helpers.isRPlus
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.databinding.DialogRenameRecordingBinding
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.models.Recording import com.simplemobiletools.voicerecorder.models.Recording
import kotlinx.android.synthetic.main.dialog_rename_recording.view.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import java.io.File import java.io.File
import com.simplemobiletools.commons.R as CommonsR
class RenameRecordingDialog(val activity: BaseSimpleActivity, val recording: Recording, val callback: () -> Unit) { class RenameRecordingDialog(val activity: BaseSimpleActivity, val recording: Recording, val callback: () -> Unit) {
init { init {
val view = activity.layoutInflater.inflate(R.layout.dialog_rename_recording, null).apply { val binding = DialogRenameRecordingBinding.inflate(activity.layoutInflater).apply {
rename_recording_title.setText(recording.title.substringBeforeLast('.')) renameRecordingTitle.setText(recording.title.substringBeforeLast('.'))
} }
val view = binding.root
activity.getAlertDialogBuilder() activity.getAlertDialogBuilder()
.setPositiveButton(R.string.ok, null) .setPositiveButton(CommonsR.string.ok, null)
.setNegativeButton(R.string.cancel, null) .setNegativeButton(CommonsR.string.cancel, null)
.apply { .apply {
activity.setupDialogStuff(view, this, R.string.rename) { alertDialog -> activity.setupDialogStuff(view, this, CommonsR.string.rename) { alertDialog ->
alertDialog.showKeyboard(view.rename_recording_title) alertDialog.showKeyboard(binding.renameRecordingTitle)
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val newTitle = view.rename_recording_title.value val newTitle = binding.renameRecordingTitle.value
if (newTitle.isEmpty()) { if (newTitle.isEmpty()) {
activity.toast(R.string.empty_name) activity.toast(CommonsR.string.empty_name)
return@setOnClickListener return@setOnClickListener
} }
if (!newTitle.isAValidFilename()) { if (!newTitle.isAValidFilename()) {
activity.toast(R.string.invalid_name) activity.toast(CommonsR.string.invalid_name)
return@setOnClickListener return@setOnClickListener
} }

View file

@ -16,19 +16,20 @@ import com.simplemobiletools.commons.helpers.isQPlus
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.activities.SimpleActivity import com.simplemobiletools.voicerecorder.activities.SimpleActivity
import com.simplemobiletools.voicerecorder.adapters.RecordingsAdapter import com.simplemobiletools.voicerecorder.adapters.RecordingsAdapter
import com.simplemobiletools.voicerecorder.databinding.FragmentPlayerBinding
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.extensions.getAllRecordings import com.simplemobiletools.voicerecorder.extensions.getAllRecordings
import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri import com.simplemobiletools.voicerecorder.helpers.getAudioFileContentUri
import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.models.Recording import com.simplemobiletools.voicerecorder.models.Recording
import kotlinx.android.synthetic.main.fragment_player.view.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import java.util.Stack import java.util.Stack
import java.util.Timer import java.util.Timer
import java.util.TimerTask import java.util.TimerTask
import com.simplemobiletools.commons.R as CommonsR
class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshRecordingsListener { class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshRecordingsListener {
private val FAST_FORWARD_SKIP_MS = 10000 private val FAST_FORWARD_SKIP_MS = 10000
@ -42,6 +43,12 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
private var prevSavePath = "" private var prevSavePath = ""
private var prevRecycleBinState = context.config.useRecycleBin private var prevRecycleBinState = context.config.useRecycleBin
private var playOnPreparation = true private var playOnPreparation = true
private lateinit var binding: FragmentPlayerBinding
override fun onFinishInflate() {
super.onFinishInflate()
binding = FragmentPlayerBinding.bind(this)
}
override fun onResume() { override fun onResume() {
setupColors() setupColors()
@ -78,23 +85,23 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
} }
private fun setupViews() { private fun setupViews() {
play_pause_btn.setOnClickListener { binding.playPauseBtn.setOnClickListener {
if (playedRecordingIDs.empty() || player_progressbar.max == 0) { if (playedRecordingIDs.empty() || binding.playerProgressbar.max == 0) {
next_btn.callOnClick() binding.nextBtn.callOnClick()
} else { } else {
togglePlayPause() togglePlayPause()
} }
} }
player_progress_current.setOnClickListener { binding.playerProgressCurrent.setOnClickListener {
skip(false) skip(false)
} }
player_progress_max.setOnClickListener { binding.playerProgressMax.setOnClickListener {
skip(true) skip(true)
} }
previous_btn.setOnClickListener { binding.previousBtn.setOnClickListener {
if (playedRecordingIDs.isEmpty()) { if (playedRecordingIDs.isEmpty()) {
return@setOnClickListener return@setOnClickListener
} }
@ -110,14 +117,14 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
playRecording(prevRecording, true) playRecording(prevRecording, true)
} }
player_title.setOnLongClickListener { binding.playerTitle.setOnLongClickListener {
if (player_title.value.isNotEmpty()) { if (binding.playerTitle.value.isNotEmpty()) {
context.copyToClipboard(player_title.value) context.copyToClipboard(binding.playerTitle.value)
} }
true true
} }
next_btn.setOnClickListener { binding.nextBtn.setOnClickListener {
val adapter = getRecordingsAdapter() val adapter = getRecordingsAdapter()
if (adapter == null || adapter.recordings.isEmpty()) { if (adapter == null || adapter.recordings.isEmpty()) {
return@setOnClickListener return@setOnClickListener
@ -137,8 +144,8 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
} }
private fun setupAdapter(recordings: ArrayList<Recording>) { private fun setupAdapter(recordings: ArrayList<Recording>) {
recordings_fastscroller.beVisibleIf(recordings.isNotEmpty()) binding.recordingsFastscroller.beVisibleIf(recordings.isNotEmpty())
recordings_placeholder.beVisibleIf(recordings.isEmpty()) binding.recordingsPlaceholder.beVisibleIf(recordings.isEmpty())
if (recordings.isEmpty()) { if (recordings.isEmpty()) {
val stringId = if (lastSearchQuery.isEmpty()) { val stringId = if (lastSearchQuery.isEmpty()) {
if (isQPlus()) { if (isQPlus()) {
@ -147,27 +154,27 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
R.string.no_recordings_in_folder_found R.string.no_recordings_in_folder_found
} }
} else { } else {
R.string.no_items_found CommonsR.string.no_items_found
} }
recordings_placeholder.text = context.getString(stringId) binding.recordingsPlaceholder.text = context.getString(stringId)
resetProgress(null) resetProgress(null)
player?.stop() player?.stop()
} }
val adapter = getRecordingsAdapter() val adapter = getRecordingsAdapter()
if (adapter == null) { if (adapter == null) {
RecordingsAdapter(context as SimpleActivity, recordings, this, recordings_list) { RecordingsAdapter(context as SimpleActivity, recordings, this, binding.recordingsList) {
playRecording(it as Recording, true) playRecording(it as Recording, true)
if (playedRecordingIDs.isEmpty() || playedRecordingIDs.peek() != it.id) { if (playedRecordingIDs.isEmpty() || playedRecordingIDs.peek() != it.id) {
playedRecordingIDs.push(it.id) playedRecordingIDs.push(it.id)
} }
}.apply { }.apply {
recordings_list.adapter = this binding.recordingsList.adapter = this
} }
if (context.areSystemAnimationsEnabled) { if (context.areSystemAnimationsEnabled) {
recordings_list.scheduleLayoutAnimation() binding.recordingsList.scheduleLayoutAnimation()
} }
} else { } else {
adapter.updateItems(recordings) adapter.updateItems(recordings)
@ -187,9 +194,9 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
setOnCompletionListener { setOnCompletionListener {
progressTimer.cancel() progressTimer.cancel()
player_progressbar.progress = player_progressbar.max binding.playerProgressbar.progress = binding.playerProgressbar.max
player_progress_current.text = player_progress_max.text binding.playerProgressCurrent.text = binding.playerProgressMax.text
play_pause_btn.setImageDrawable(getToggleButtonIcon(false)) binding.playPauseBtn.setImageDrawable(getToggleButtonIcon(false))
} }
setOnPreparedListener { setOnPreparedListener {
@ -205,7 +212,7 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
override fun playRecording(recording: Recording, playOnPrepared: Boolean) { override fun playRecording(recording: Recording, playOnPrepared: Boolean) {
resetProgress(recording) resetProgress(recording)
(recordings_list.adapter as RecordingsAdapter).updateCurrentRecording(recording.id) (binding.recordingsList.adapter as RecordingsAdapter).updateCurrentRecording(recording.id)
playOnPreparation = playOnPrepared playOnPreparation = playOnPrepared
player!!.apply { player!!.apply {
@ -239,12 +246,12 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
} }
} }
play_pause_btn.setImageDrawable(getToggleButtonIcon(playOnPreparation)) binding.playPauseBtn.setImageDrawable(getToggleButtonIcon(playOnPreparation))
player_progressbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { binding.playerProgressbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser && !playedRecordingIDs.isEmpty()) { if (fromUser && !playedRecordingIDs.isEmpty()) {
player?.seekTo(progress * 1000) player?.seekTo(progress * 1000)
player_progress_current.text = progress.getFormattedDuration() binding.playerProgressCurrent.text = progress.getFormattedDuration()
resumePlayback() resumePlayback()
} }
} }
@ -267,22 +274,22 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
if (player != null) { if (player != null) {
val progress = Math.round(player!!.currentPosition / 1000.toDouble()).toInt() val progress = Math.round(player!!.currentPosition / 1000.toDouble()).toInt()
updateCurrentProgress(progress) updateCurrentProgress(progress)
player_progressbar.progress = progress binding.playerProgressbar.progress = progress
} }
} }
} }
} }
private fun updateCurrentProgress(seconds: Int) { private fun updateCurrentProgress(seconds: Int) {
player_progress_current.text = seconds.getFormattedDuration() binding.playerProgressCurrent.text = seconds.getFormattedDuration()
} }
private fun resetProgress(recording: Recording?) { private fun resetProgress(recording: Recording?) {
updateCurrentProgress(0) updateCurrentProgress(0)
player_progressbar.progress = 0 binding.playerProgressbar.progress = 0
player_progressbar.max = recording?.duration ?: 0 binding.playerProgressbar.max = recording?.duration ?: 0
player_title.text = recording?.title ?: "" binding.playerTitle.text = recording?.title ?: ""
player_progress_max.text = (recording?.duration ?: 0).getFormattedDuration() binding.playerProgressMax.text = (recording?.duration ?: 0).getFormattedDuration()
} }
fun onSearchTextChanged(text: String) { fun onSearchTextChanged(text: String) {
@ -301,18 +308,18 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
private fun pausePlayback() { private fun pausePlayback() {
player?.pause() player?.pause()
play_pause_btn.setImageDrawable(getToggleButtonIcon(false)) binding.playPauseBtn.setImageDrawable(getToggleButtonIcon(false))
progressTimer.cancel() progressTimer.cancel()
} }
private fun resumePlayback() { private fun resumePlayback() {
player?.start() player?.start()
play_pause_btn.setImageDrawable(getToggleButtonIcon(true)) binding.playPauseBtn.setImageDrawable(getToggleButtonIcon(true))
setupProgressTimer() setupProgressTimer()
} }
private fun getToggleButtonIcon(isPlaying: Boolean): Drawable { private fun getToggleButtonIcon(isPlaying: Boolean): Drawable {
val drawable = if (isPlaying) R.drawable.ic_pause_vector else R.drawable.ic_play_vector val drawable = if (isPlaying) CommonsR.drawable.ic_pause_vector else CommonsR.drawable.ic_play_vector
return resources.getColoredDrawableWithColor(drawable, context.getProperPrimaryColor().getContrastColor()) return resources.getColoredDrawableWithColor(drawable, context.getProperPrimaryColor().getContrastColor())
} }
@ -333,7 +340,7 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
private fun getIsPlaying() = player?.isPlaying == true private fun getIsPlaying() = player?.isPlaying == true
private fun getRecordingsAdapter() = recordings_list.adapter as? RecordingsAdapter private fun getRecordingsAdapter() = binding.recordingsList.adapter as? RecordingsAdapter
private fun storePrevState() { private fun storePrevState() {
prevSavePath = context!!.config.saveRecordingsFolder prevSavePath = context!!.config.saveRecordingsFolder
@ -342,16 +349,16 @@ class PlayerFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
private fun setupColors() { private fun setupColors() {
val properPrimaryColor = context.getProperPrimaryColor() val properPrimaryColor = context.getProperPrimaryColor()
recordings_fastscroller.updateColors(properPrimaryColor) binding.recordingsFastscroller.updateColors(properPrimaryColor)
context.updateTextColors(player_holder) context.updateTextColors(binding.playerHolder)
val textColor = context.getProperTextColor() val textColor = context.getProperTextColor()
arrayListOf(previous_btn, next_btn).forEach { arrayListOf(binding.previousBtn, binding.nextBtn).forEach {
it.applyColorFilter(textColor) it.applyColorFilter(textColor)
} }
play_pause_btn.background.applyColorFilter(properPrimaryColor) binding.playPauseBtn.background.applyColorFilter(properPrimaryColor)
play_pause_btn.setImageDrawable(getToggleButtonIcon(false)) binding.playPauseBtn.setImageDrawable(getToggleButtonIcon(false))
} }
fun finishActMode() = getRecordingsAdapter()?.finishActMode() fun finishActMode() = getRecordingsAdapter()?.finishActMode()

View file

@ -10,24 +10,27 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.isNougatPlus import com.simplemobiletools.commons.helpers.isNougatPlus
import com.simplemobiletools.voicerecorder.R import com.simplemobiletools.voicerecorder.databinding.FragmentRecorderBinding
import com.simplemobiletools.voicerecorder.helpers.* import com.simplemobiletools.voicerecorder.helpers.*
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.services.RecorderService import com.simplemobiletools.voicerecorder.services.RecorderService
import kotlinx.android.synthetic.main.fragment_recorder.view.recorder_visualizer
import kotlinx.android.synthetic.main.fragment_recorder.view.recording_duration
import kotlinx.android.synthetic.main.fragment_recorder.view.toggle_pause_button
import kotlinx.android.synthetic.main.fragment_recorder.view.toggle_recording_button
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import java.util.Timer import java.util.Timer
import java.util.TimerTask import java.util.TimerTask
import com.simplemobiletools.commons.R as CommonsR
class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) { class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
private var status = RECORDING_STOPPED private var status = RECORDING_STOPPED
private var pauseBlinkTimer = Timer() private var pauseBlinkTimer = Timer()
private var bus: EventBus? = null private var bus: EventBus? = null
private lateinit var binding: FragmentRecorderBinding
override fun onFinishInflate() {
super.onFinishInflate()
binding = FragmentRecorderBinding.bind(this)
}
override fun onResume() { override fun onResume() {
setupColors() setupColors()
@ -46,24 +49,24 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
super.onAttachedToWindow() super.onAttachedToWindow()
setupColors() setupColors()
recorder_visualizer.recreate() binding.recorderVisualizer.recreate()
bus = EventBus.getDefault() bus = EventBus.getDefault()
bus!!.register(this) bus!!.register(this)
updateRecordingDuration(0) updateRecordingDuration(0)
toggle_recording_button.setOnClickListener { binding.toggleRecordingButton.setOnClickListener {
(context as? BaseSimpleActivity)?.handleNotificationPermission { granted -> (context as? BaseSimpleActivity)?.handleNotificationPermission { granted ->
if (granted) { if (granted) {
toggleRecording() toggleRecording()
} else { } else {
PermissionRequiredDialog(context as BaseSimpleActivity, R.string.allow_notifications_voice_recorder, { PermissionRequiredDialog(context as BaseSimpleActivity, CommonsR.string.allow_notifications_voice_recorder, {
(context as BaseSimpleActivity).openNotificationSettings() (context as BaseSimpleActivity).openNotificationSettings()
}) })
} }
} }
} }
toggle_pause_button.setOnClickListener { binding.togglePauseButton.setOnClickListener {
Intent(context, RecorderService::class.java).apply { Intent(context, RecorderService::class.java).apply {
action = TOGGLE_PAUSE action = TOGGLE_PAUSE
context.startService(this) context.startService(this)
@ -81,26 +84,27 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
private fun setupColors() { private fun setupColors() {
val properPrimaryColor = context.getProperPrimaryColor() val properPrimaryColor = context.getProperPrimaryColor()
toggle_recording_button.apply { binding.toggleRecordingButton.apply {
setImageDrawable(getToggleButtonIcon()) setImageDrawable(getToggleButtonIcon())
background.applyColorFilter(properPrimaryColor) background.applyColorFilter(properPrimaryColor)
} }
toggle_pause_button.apply { binding.togglePauseButton.apply {
setImageDrawable(resources.getColoredDrawableWithColor(R.drawable.ic_pause_vector, properPrimaryColor.getContrastColor())) setImageDrawable(resources.getColoredDrawableWithColor(CommonsR.drawable.ic_pause_vector, properPrimaryColor.getContrastColor()))
background.applyColorFilter(properPrimaryColor) background.applyColorFilter(properPrimaryColor)
} }
recorder_visualizer.chunkColor = properPrimaryColor binding.recorderVisualizer.chunkColor = properPrimaryColor
recording_duration.setTextColor(context.getProperTextColor()) binding.recordingDuration.setTextColor(context.getProperTextColor())
} }
private fun updateRecordingDuration(duration: Int) { private fun updateRecordingDuration(duration: Int) {
recording_duration.text = duration.getFormattedDuration() binding.recordingDuration.text = duration.getFormattedDuration()
} }
private fun getToggleButtonIcon(): Drawable { private fun getToggleButtonIcon(): Drawable {
val drawable = if (status == RECORDING_RUNNING || status == RECORDING_PAUSED) R.drawable.ic_stop_vector else R.drawable.ic_microphone_vector val drawable =
if (status == RECORDING_RUNNING || status == RECORDING_PAUSED) CommonsR.drawable.ic_stop_vector else CommonsR.drawable.ic_microphone_vector
return resources.getColoredDrawableWithColor(drawable, context.getProperPrimaryColor().getContrastColor()) return resources.getColoredDrawableWithColor(drawable, context.getProperPrimaryColor().getContrastColor())
} }
@ -111,12 +115,12 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
RECORDING_RUNNING RECORDING_RUNNING
} }
toggle_recording_button.setImageDrawable(getToggleButtonIcon()) binding.toggleRecordingButton.setImageDrawable(getToggleButtonIcon())
if (status == RECORDING_RUNNING) { if (status == RECORDING_RUNNING) {
startRecording() startRecording()
} else { } else {
toggle_pause_button.beGone() binding.togglePauseButton.beGone()
stopRecording() stopRecording()
} }
} }
@ -125,7 +129,7 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
Intent(context, RecorderService::class.java).apply { Intent(context, RecorderService::class.java).apply {
context.startService(this) context.startService(this)
} }
recorder_visualizer.recreate() binding.recorderVisualizer.recreate()
} }
private fun stopRecording() { private fun stopRecording() {
@ -139,15 +143,15 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
if (status == RECORDING_PAUSED) { if (status == RECORDING_PAUSED) {
// update just the alpha so that it will always be clickable // update just the alpha so that it will always be clickable
Handler(Looper.getMainLooper()).post { Handler(Looper.getMainLooper()).post {
toggle_pause_button.alpha = if (toggle_pause_button.alpha == 0f) 1f else 0f binding.togglePauseButton.alpha = if (binding.togglePauseButton.alpha == 0f) 1f else 0f
} }
} }
} }
} }
private fun refreshView() { private fun refreshView() {
toggle_recording_button.setImageDrawable(getToggleButtonIcon()) binding.toggleRecordingButton.setImageDrawable(getToggleButtonIcon())
toggle_pause_button.beVisibleIf(status != RECORDING_STOPPED && isNougatPlus()) binding.togglePauseButton.beVisibleIf(status != RECORDING_STOPPED && isNougatPlus())
pauseBlinkTimer.cancel() pauseBlinkTimer.cancel()
if (status == RECORDING_PAUSED) { if (status == RECORDING_PAUSED) {
@ -156,7 +160,7 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
} }
if (status == RECORDING_RUNNING) { if (status == RECORDING_RUNNING) {
toggle_pause_button.alpha = 1f binding.togglePauseButton.alpha = 1f
} }
} }
@ -175,7 +179,7 @@ class RecorderFragment(context: Context, attributeSet: AttributeSet) : MyViewPag
fun gotAmplitudeEvent(event: Events.RecordingAmplitude) { fun gotAmplitudeEvent(event: Events.RecordingAmplitude) {
val amplitude = event.amplitude val amplitude = event.amplitude
if (status == RECORDING_RUNNING) { if (status == RECORDING_RUNNING) {
recorder_visualizer.update(amplitude) binding.recorderVisualizer.update(amplitude)
} }
} }
} }

View file

@ -3,27 +3,30 @@ package com.simplemobiletools.voicerecorder.fragments
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.activities.SimpleActivity import com.simplemobiletools.voicerecorder.activities.SimpleActivity
import com.simplemobiletools.voicerecorder.adapters.TrashAdapter import com.simplemobiletools.voicerecorder.adapters.TrashAdapter
import com.simplemobiletools.voicerecorder.databinding.FragmentTrashBinding
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.extensions.getAllRecordings import com.simplemobiletools.voicerecorder.extensions.getAllRecordings
import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener import com.simplemobiletools.voicerecorder.interfaces.RefreshRecordingsListener
import com.simplemobiletools.voicerecorder.models.Events import com.simplemobiletools.voicerecorder.models.Events
import com.simplemobiletools.voicerecorder.models.Recording import com.simplemobiletools.voicerecorder.models.Recording
import kotlinx.android.synthetic.main.fragment_trash.view.trash_fastscroller
import kotlinx.android.synthetic.main.fragment_trash.view.trash_holder
import kotlinx.android.synthetic.main.fragment_trash.view.trash_list
import kotlinx.android.synthetic.main.fragment_trash.view.trash_placeholder
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode import org.greenrobot.eventbus.ThreadMode
import com.simplemobiletools.commons.R as CommonsR
class TrashFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshRecordingsListener { class TrashFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet), RefreshRecordingsListener {
private var itemsIgnoringSearch = ArrayList<Recording>() private var itemsIgnoringSearch = ArrayList<Recording>()
private var lastSearchQuery = "" private var lastSearchQuery = ""
private var bus: EventBus? = null private var bus: EventBus? = null
private var prevSavePath = "" private var prevSavePath = ""
private lateinit var binding: FragmentTrashBinding
override fun onFinishInflate() {
super.onFinishInflate()
binding = FragmentTrashBinding.bind(this)
}
override fun onResume() { override fun onResume() {
setupColors() setupColors()
@ -60,26 +63,26 @@ class TrashFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
override fun playRecording(recording: Recording, playOnPrepared: Boolean) {} override fun playRecording(recording: Recording, playOnPrepared: Boolean) {}
private fun setupAdapter(recordings: ArrayList<Recording>) { private fun setupAdapter(recordings: ArrayList<Recording>) {
trash_fastscroller.beVisibleIf(recordings.isNotEmpty()) binding.trashFastscroller.beVisibleIf(recordings.isNotEmpty())
trash_placeholder.beVisibleIf(recordings.isEmpty()) binding.trashPlaceholder.beVisibleIf(recordings.isEmpty())
if (recordings.isEmpty()) { if (recordings.isEmpty()) {
val stringId = if (lastSearchQuery.isEmpty()) { val stringId = if (lastSearchQuery.isEmpty()) {
R.string.recycle_bin_empty CommonsR.string.recycle_bin_empty
} else { } else {
R.string.no_items_found CommonsR.string.no_items_found
} }
trash_placeholder.text = context.getString(stringId) binding.trashPlaceholder.text = context.getString(stringId)
} }
val adapter = getRecordingsAdapter() val adapter = getRecordingsAdapter()
if (adapter == null) { if (adapter == null) {
TrashAdapter(context as SimpleActivity, recordings, this, trash_list).apply { TrashAdapter(context as SimpleActivity, recordings, this, binding.trashList).apply {
trash_list.adapter = this binding.trashList.adapter = this
} }
if (context.areSystemAnimationsEnabled) { if (context.areSystemAnimationsEnabled) {
trash_list.scheduleLayoutAnimation() binding.trashList.scheduleLayoutAnimation()
} }
} else { } else {
adapter.updateItems(recordings) adapter.updateItems(recordings)
@ -98,7 +101,7 @@ class TrashFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
setupAdapter(filtered) setupAdapter(filtered)
} }
private fun getRecordingsAdapter() = trash_list.adapter as? TrashAdapter private fun getRecordingsAdapter() = binding.trashList.adapter as? TrashAdapter
private fun storePrevPath() { private fun storePrevPath() {
prevSavePath = context!!.config.saveRecordingsFolder prevSavePath = context!!.config.saveRecordingsFolder
@ -106,8 +109,8 @@ class TrashFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerF
private fun setupColors() { private fun setupColors() {
val properPrimaryColor = context.getProperPrimaryColor() val properPrimaryColor = context.getProperPrimaryColor()
trash_fastscroller.updateColors(properPrimaryColor) binding.trashFastscroller.updateColors(properPrimaryColor)
context.updateTextColors(trash_holder) context.updateTextColors(binding.trashHolder)
} }
fun finishActMode() = getRecordingsAdapter()?.finishActMode() fun finishActMode() = getRecordingsAdapter()?.finishActMode()

View file

@ -14,6 +14,7 @@ import com.simplemobiletools.voicerecorder.R
import com.simplemobiletools.voicerecorder.activities.BackgroundRecordActivity import com.simplemobiletools.voicerecorder.activities.BackgroundRecordActivity
import com.simplemobiletools.voicerecorder.extensions.config import com.simplemobiletools.voicerecorder.extensions.config
import com.simplemobiletools.voicerecorder.extensions.drawableToBitmap import com.simplemobiletools.voicerecorder.extensions.drawableToBitmap
import com.simplemobiletools.commons.R as CommonsR
class MyWidgetRecordDisplayProvider : AppWidgetProvider() { class MyWidgetRecordDisplayProvider : AppWidgetProvider() {
private val OPEN_APP_INTENT_ID = 1 private val OPEN_APP_INTENT_ID = 1
@ -57,7 +58,7 @@ class MyWidgetRecordDisplayProvider : AppWidgetProvider() {
} }
private fun getColoredIcon(context: Context, color: Int, alpha: Int): Bitmap { private fun getColoredIcon(context: Context, color: Int, alpha: Int): Bitmap {
val drawable = context.resources.getColoredDrawableWithColor(R.drawable.ic_microphone_vector, color, alpha) val drawable = context.resources.getColoredDrawableWithColor(CommonsR.drawable.ic_microphone_vector, color, alpha)
return context.drawableToBitmap(drawable) return context.drawableToBitmap(drawable)
} }
} }

View file

@ -30,6 +30,7 @@ import com.simplemobiletools.voicerecorder.recorder.Recorder
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import java.io.File import java.io.File
import java.util.* import java.util.*
import com.simplemobiletools.commons.R as CommonsR
class RecorderService : Service() { class RecorderService : Service() {
companion object { companion object {
@ -195,7 +196,7 @@ class RecorderService : Service() {
val newUri = contentResolver.insert(audioCollection, newSongDetails) val newUri = contentResolver.insert(audioCollection, newSongDetails)
if (newUri == null) { if (newUri == null) {
toast(R.string.unknown_error_occurred) toast(CommonsR.string.unknown_error_occurred)
return return
} }
@ -257,7 +258,7 @@ class RecorderService : Service() {
} }
var priority = Notification.PRIORITY_DEFAULT var priority = Notification.PRIORITY_DEFAULT
var icon = R.drawable.ic_microphone_vector var icon = CommonsR.drawable.ic_microphone_vector
var title = label var title = label
var visibility = NotificationCompat.VISIBILITY_PUBLIC var visibility = NotificationCompat.VISIBILITY_PUBLIC
var text = getString(R.string.recording) var text = getString(R.string.recording)

View file

@ -1,29 +0,0 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
mavenCentral()
maven { url "https://jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

5
build.gradle.kts Normal file
View file

@ -0,0 +1,5 @@
plugins {
alias(libs.plugins.android).apply(false)
alias(libs.plugins.kotlinAndroid).apply(false)
alias(libs.plugins.ksp).apply(false)
}

61
gradle/libs.versions.toml Normal file
View file

@ -0,0 +1,61 @@
[versions]
#jetbrains
kotlin = "1.9.0"
#KSP
ksp = "1.9.0-1.0.12"
#AndroidX
androidx-constraintlayout = "2.1.4"
androidx-documentfile = "1.0.1"
androidx-swiperefreshlayout = "1.1.0"
#Eventbus
eventbus = "3.3.1"
#Room
room = "2.6.0-alpha02"
#Simple tools
simple-commons = "c5a32fb1f3"
#AudioRecordView
audiorecordview = "1.0.4"
#TAndroidLame
tandroidlame = "1.1"
#AutofitTextView
autofittextview = "0.2.1"
#Gradle
gradlePlugins-agp = "8.1.0"
#build
app-build-compileSDKVersion = "34"
app-build-targetSDK = "34"
app-build-minimumSDK = "23"
app-build-javaVersion = "VERSION_17"
app-build-kotlinJVMTarget = "17"
#versioning
app-version-appId = "com.simplemobiletools.voicerecorder"
app-version-versionCode = "38"
app-version-versionName = "5.12.0"
[libraries]
#AndroidX
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" }
androidx-documentfile = { module = "androidx.documentfile:documentfile", version.ref = "androidx-documentfile" }
androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "androidx-swiperefreshlayout" }
#Room
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
#Simple Mobile Tools
simple-tools-commons = { module = "com.github.SimpleMobileTools:Simple-Commons", version.ref = "simple-commons" }
#EventBus
eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbus" }
#AudioRecordView
audiorecordview = { module = "com.github.Armen101:AudioRecordView", version.ref = "audiorecordview" }
#TAndroidLame
tandroidlame = { module = "com.github.naman14:TAndroidLame", version.ref = "tandroidlame" }
#AutofitTextView
autofittextview = { module = "me.grantland:autofittextview", version.ref = "autofittextview" }
[bundles]
room = [
"androidx-room-ktx",
"androidx-room-runtime",
]
[plugins]
android = { id = "com.android.application", version.ref = "gradlePlugins-agp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }

View file

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip

View file

@ -1 +0,0 @@
include ':app'

16
settings.gradle.kts Normal file
View file

@ -0,0 +1,16 @@
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { setUrl("https://jitpack.io") }
}
}
include(":app")