diff --git a/.gitignore b/.gitignore index feed2e4..2df6459 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ .cxx local.properties app/release/ +app/google-services.json diff --git a/app/.gitignore b/app/.gitignore index 42afabf..65d12b9 100644 --- a/app/.gitignore +++ b/app/.gitignore @@ -1 +1,2 @@ -/build \ No newline at end of file +/build +google-services.json \ No newline at end of file diff --git a/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt b/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt index d165577..2ba9ea2 100644 --- a/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt +++ b/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt @@ -107,3 +107,11 @@ fun Context.shareFiles(uris: List): Boolean { false } } + +fun Context.startActivitySafely(intent: Intent) { + try { + startActivity(intent) + } catch (e: ActivityNotFoundException) { + // Todo + } +} diff --git a/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt new file mode 100644 index 0000000..78b2288 --- /dev/null +++ b/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt @@ -0,0 +1,45 @@ +package com.sn.snfilemanager.feature.about + +import android.content.Intent +import android.net.Uri +import androidx.navigation.fragment.findNavController +import com.sn.snfilemanager.core.base.BaseFragment +import com.sn.snfilemanager.core.extensions.click +import com.sn.snfilemanager.core.extensions.startActivitySafely +import com.sn.snfilemanager.databinding.FragmentAboutBinding +import com.sn.snfilemanager.view.dialog.license.LicenseDialog + +class AboutFragment : BaseFragment() { + override fun getViewModelClass() = AboutViewModel::class.java + + override fun getViewBinding() = FragmentAboutBinding.inflate(layoutInflater) + + companion object { + const val GITHUB_URL = + "https://github.com/emreesen27/Android-Sn-File-Manager" + const val PRIVACY_URL = + "https://github.com/emreesen27/Android-Sn-File-Manager/blob/develop/PRIVACY.md" + } + + override fun setupViews() { + binding.vm = viewModel + binding.lifecycleOwner = viewLifecycleOwner + initClicks() + } + + private fun initClicks() { + binding.toolbar.setNavigationOnClickListener { findNavController().popBackStack() } + binding.btnGithub.click { openUrl(GITHUB_URL) } + binding.btnLicense.click { showLicensesDialog() } + binding.btnPrivacy.click { openUrl(PRIVACY_URL) } + } + + private fun showLicensesDialog() { + LicenseDialog().show(childFragmentManager, LicenseDialog.TAG) + } + + private fun openUrl(url: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + context?.startActivitySafely(intent) + } +} diff --git a/app/src/main/java/com/sn/snfilemanager/feature/about/AboutViewModel.kt b/app/src/main/java/com/sn/snfilemanager/feature/about/AboutViewModel.kt new file mode 100644 index 0000000..a19cc2c --- /dev/null +++ b/app/src/main/java/com/sn/snfilemanager/feature/about/AboutViewModel.kt @@ -0,0 +1,19 @@ +package com.sn.snfilemanager.feature.about + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import com.sn.snfilemanager.BuildConfig + +class AboutViewModel : ViewModel() { + private val _versionLiveData: MutableLiveData = MutableLiveData() + val versionLiveData: LiveData = _versionLiveData + + init { + getVersion() + } + + private fun getVersion() { + _versionLiveData.value = BuildConfig.VERSION_NAME + } +} diff --git a/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt index 91a4c48..8970f12 100644 --- a/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt +++ b/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt @@ -290,6 +290,9 @@ class HomeFragment : BaseFragment() { btnSettings.click { navigate(HomeFragmentDirections.actionSettings()) } + btnAbout.click { + navigate(HomeFragmentDirections.actionAbout()) + } } } } diff --git a/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsFragment.kt index 7cd6cfd..83001e8 100644 --- a/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsFragment.kt +++ b/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsFragment.kt @@ -4,7 +4,6 @@ import android.content.SharedPreferences import android.content.SharedPreferences.OnSharedPreferenceChangeListener import android.os.Bundle import androidx.preference.ListPreference -import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreferenceCompat import com.sn.snfilemanager.R @@ -19,13 +18,6 @@ class SettingsFragment : PreferenceFragmentCompat() { ) { setPreferencesFromResource(R.xml.preferences, rootKey) - val aboutButton: Preference? = findPreference(SettingsUtils.SN_ABOUT) - aboutButton?.setOnPreferenceClickListener { - // todo - // findNavController().navigate(SettingsFragmentDirections.actionSettingsToAbout()) - true - } - val themeListPreference: ListPreference? = findPreference(SettingsUtils.SN_THEME_MODE) val hiddenFilePreference: SwitchPreferenceCompat? = findPreference(SettingsUtils.SN_HIDDEN_FILE) diff --git a/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsToolbar.kt b/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsToolbar.kt new file mode 100644 index 0000000..83a9188 --- /dev/null +++ b/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsToolbar.kt @@ -0,0 +1,26 @@ +package com.sn.snfilemanager.feature.settings + +import android.content.Context +import android.util.AttributeSet +import androidx.navigation.findNavController +import androidx.preference.Preference +import androidx.preference.PreferenceViewHolder +import com.google.android.material.appbar.MaterialToolbar +import com.sn.snfilemanager.R + +class SettingsToolbar + @JvmOverloads + constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + ) : Preference(context, attrs, defStyleAttr) { + override fun onBindViewHolder(holder: PreferenceViewHolder) { + super.onBindViewHolder(holder) + + val toolbar = holder.findViewById(R.id.toolbar_settings) as MaterialToolbar + toolbar.setNavigationOnClickListener { + toolbar.findNavController().popBackStack() + } + } + } diff --git a/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsUtils.kt b/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsUtils.kt index 074a449..d51ff68 100644 --- a/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsUtils.kt +++ b/app/src/main/java/com/sn/snfilemanager/feature/settings/SettingsUtils.kt @@ -5,10 +5,7 @@ import androidx.appcompat.app.AppCompatDelegate import androidx.preference.PreferenceManager object SettingsUtils { - const val SECRETIVE_REPOSITORY_LINK = "https://github.com/emreesen27/Secretive" - const val SN_THEME_MODE = "sn.theme.mode" - const val SN_ABOUT = "sn.about" const val SN_HIDDEN_FILE = "sn.hidden.file" const val SYSTEM = "System" diff --git a/app/src/main/java/com/sn/snfilemanager/view/component/HrImageButton.kt b/app/src/main/java/com/sn/snfilemanager/view/component/HrImageButton.kt index 04b0ef6..a3c38be 100644 --- a/app/src/main/java/com/sn/snfilemanager/view/component/HrImageButton.kt +++ b/app/src/main/java/com/sn/snfilemanager/view/component/HrImageButton.kt @@ -6,6 +6,8 @@ import androidx.appcompat.widget.AppCompatImageView import androidx.constraintlayout.widget.ConstraintLayout import com.google.android.material.textview.MaterialTextView import com.sn.snfilemanager.R +import com.sn.snfilemanager.core.extensions.gone +import com.sn.snfilemanager.core.extensions.visible class HrImageButton @JvmOverloads @@ -23,10 +25,11 @@ class HrImageButton titleTextView.text = value } - var subTitle: String + var subTitle: String? get() = subTitleTextView.text.toString() set(value) { subTitleTextView.text = value + checkSubTitle() } init { @@ -44,4 +47,12 @@ class HrImageButton attributes.recycle() } + + private fun checkSubTitle() { + if (subTitle.isNullOrEmpty()) { + subTitleTextView.gone() + } else { + subTitleTextView.visible() + } + } } diff --git a/app/src/main/java/com/sn/snfilemanager/view/dialog/license/License.kt b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/License.kt new file mode 100644 index 0000000..fe002c6 --- /dev/null +++ b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/License.kt @@ -0,0 +1,7 @@ +package com.sn.snfilemanager.view.dialog.license + +data class License( + val name: String, + val url: String, + val license: String, +) diff --git a/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt new file mode 100644 index 0000000..464d29e --- /dev/null +++ b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt @@ -0,0 +1,95 @@ +package com.sn.snfilemanager.view.dialog.license + +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.sn.snfilemanager.core.extensions.click +import com.sn.snfilemanager.core.extensions.startActivitySafely +import com.sn.snfilemanager.databinding.ItemLicenseBinding + +class LicenseAdapter(private val context: Context) : + RecyclerView.Adapter() { + private val licenses: List = + listOf( + License( + "Glide", + "https://github.com/bumptech/glide", + "https://github.com/bumptech/glide/blob/master/LICENSE", + ), + License( + "Nested Progress", + "https://github.com/emreesen27/Android-Nested-Progress", + "https://github.com/emreesen27/Android-Nested-Progress/blob/master/LICENSE", + ), + License( + "Toasty", + "https://github.com/GrenderG/Toasty", + "https://github.com/GrenderG/Toasty/blob/master/LICENSE", + ), + License( + "Lottie Android", + "https://github.com/airbnb/lottie-android", + "https://github.com/airbnb/lottie-android/blob/master/LICENSE", + ), + License( + "Ssp", + "https://github.com/intuit/ssp", + "https://github.com/intuit/ssp/blob/master/LICENSE", + ), + License( + "Android Animation", + "https://github.com/gayanvoice/android-animations", + "https://github.com/gayanvoice/android-animations/blob/master/LICENSE", + ), + ) + + override fun onCreateViewHolder( + parent: ViewGroup, + viewType: Int, + ): LicenseAdapter.LicenseViewHolder { + val binding = + ItemLicenseBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return LicenseViewHolder(binding) + } + + override fun onBindViewHolder( + holder: LicenseAdapter.LicenseViewHolder, + position: Int, + ) { + holder.bind(licenses[position]) + } + + override fun getItemCount(): Int { + return licenses.size + } + + inner class LicenseViewHolder(private val binding: ItemLicenseBinding) : + RecyclerView.ViewHolder(binding.root) { + init { + binding.mtvGithub.click { + if (adapterPosition != RecyclerView.NO_POSITION) { + val clickedLicense = licenses[adapterPosition] + openUrl(clickedLicense.url) + } + } + binding.mtvLicense.click { + if (adapterPosition != RecyclerView.NO_POSITION) { + val clickedLicense = licenses[adapterPosition] + openUrl(clickedLicense.license) + } + } + } + + fun bind(model: License) { + binding.mtvName.text = model.name + } + } + + private fun openUrl(url: String) { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url)) + context.startActivitySafely(intent) + } +} diff --git a/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseDialog.kt b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseDialog.kt new file mode 100644 index 0000000..3cf9418 --- /dev/null +++ b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseDialog.kt @@ -0,0 +1,52 @@ +package com.sn.snfilemanager.view.dialog.license + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.fragment.app.DialogFragment +import com.sn.snfilemanager.R +import com.sn.snfilemanager.core.extensions.click +import com.sn.snfilemanager.databinding.DialogLicenseBinding + +class LicenseDialog : DialogFragment() { + companion object { + const val TAG = "LICENSE_DIALOG" + } + + private val binding: DialogLicenseBinding by lazy { + DialogLicenseBinding.inflate(layoutInflater) + } + + override fun onStart() { + super.onStart() + dialog?.window?.setLayout( + ConstraintLayout.LayoutParams.MATCH_PARENT, + ConstraintLayout.LayoutParams.MATCH_PARENT, + ) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setStyle(STYLE_NO_TITLE, R.style.DialogTheme_transparent) + dialog?.window?.setBackgroundDrawableResource(R.drawable.dialog_rounded) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + return binding.root + } + + override fun onViewCreated( + view: View, + savedInstanceState: Bundle?, + ) { + super.onViewCreated(view, savedInstanceState) + binding.recycler.adapter = LicenseAdapter(requireContext()) + binding.ivClose.click { dismiss() } + } +} diff --git a/app/src/main/res/drawable/ic_app_icon_small.xml b/app/src/main/res/drawable/ic_app_icon_small.xml new file mode 100644 index 0000000..8d92bcb --- /dev/null +++ b/app/src/main/res/drawable/ic_app_icon_small.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_circle_small.xml b/app/src/main/res/drawable/ic_circle_small.xml new file mode 100644 index 0000000..a47d58b --- /dev/null +++ b/app/src/main/res/drawable/ic_circle_small.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_github.xml b/app/src/main/res/drawable/ic_github.xml new file mode 100644 index 0000000..a916142 --- /dev/null +++ b/app/src/main/res/drawable/ic_github.xml @@ -0,0 +1,15 @@ + + + diff --git a/app/src/main/res/drawable/ic_info_small.xml b/app/src/main/res/drawable/ic_info_small.xml new file mode 100644 index 0000000..0d972c0 --- /dev/null +++ b/app/src/main/res/drawable/ic_info_small.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/ic_license.xml b/app/src/main/res/drawable/ic_license.xml new file mode 100644 index 0000000..0975d4f --- /dev/null +++ b/app/src/main/res/drawable/ic_license.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/ic_privacy.xml b/app/src/main/res/drawable/ic_privacy.xml new file mode 100644 index 0000000..2f269d7 --- /dev/null +++ b/app/src/main/res/drawable/ic_privacy.xml @@ -0,0 +1,55 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_license.xml b/app/src/main/res/layout/dialog_license.xml new file mode 100644 index 0000000..08380ef --- /dev/null +++ b/app/src/main/res/layout/dialog_license.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_about.xml b/app/src/main/res/layout/fragment_about.xml new file mode 100644 index 0000000..26927dc --- /dev/null +++ b/app/src/main/res/layout/fragment_about.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_license.xml b/app/src/main/res/layout/item_license.xml new file mode 100644 index 0000000..ced86be --- /dev/null +++ b/app/src/main/res/layout/item_license.xml @@ -0,0 +1,52 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_preference.xml b/app/src/main/res/layout/item_preference.xml index b4436fa..79984b5 100644 --- a/app/src/main/res/layout/item_preference.xml +++ b/app/src/main/res/layout/item_preference.xml @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/_10sdp" - android:layout_marginTop="@dimen/_8sdp" + android:layout_marginTop="@dimen/_5sdp" android:layout_marginBottom="@dimen/_3sdp" android:orientation="vertical" android:padding="5dp"> @@ -23,6 +23,7 @@ android:id="@android:id/summary" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/_15sdp" android:fontFamily="@font/adamina" android:paddingHorizontal="@dimen/_3sdp" android:textColor="@color/second_text_color" diff --git a/app/src/main/res/layout/item_switch_preference.xml b/app/src/main/res/layout/item_switch_preference.xml index e8c5833..6e5c0aa 100644 --- a/app/src/main/res/layout/item_switch_preference.xml +++ b/app/src/main/res/layout/item_switch_preference.xml @@ -5,7 +5,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/_10sdp" - android:layout_marginTop="@dimen/_8sdp" + android:layout_marginTop="@dimen/_5sdp" android:layout_marginBottom="@dimen/_3sdp" android:padding="5dp"> diff --git a/app/src/main/res/layout/toolbar_settings.xml b/app/src/main/res/layout/toolbar_settings.xml new file mode 100644 index 0000000..4879e48 --- /dev/null +++ b/app/src/main/res/layout/toolbar_settings.xml @@ -0,0 +1,28 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/navigation.xml b/app/src/main/res/navigation/navigation.xml index 30f5383..a7b3f27 100644 --- a/app/src/main/res/navigation/navigation.xml +++ b/app/src/main/res/navigation/navigation.xml @@ -51,6 +51,10 @@ android:id="@+id/action_settings" app:destination="@+id/settings_fragment" /> + + + app:argType="string" /> @@ -89,7 +93,7 @@ + app:argType="string" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e07eec7..7cd5813 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -7,6 +7,7 @@ Open source license Privacy policy Settings + Version Home Filter Search @@ -93,4 +94,9 @@ Please enter at least 3 characters to start searching Target and source cannot be the same Choose a directory + View on Github + Licenses + Github + License + Third party licenses \ No newline at end of file diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 314a2c0..c95edf9 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -2,6 +2,11 @@ + + @@ -32,11 +37,4 @@ - - \ No newline at end of file