From 0f84732f80fc847c57e432c8f8b86b9627376ec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Thu, 25 Mar 2021 15:50:14 +0100 Subject: [PATCH] [UI/Settings] Add new profile config dialog. Implement choosing background images. --- app/build.gradle | 2 +- .../szczodrzynski/edziennik/MainActivity.kt | 55 ++--- .../edziennik/MainActivityRequestHandler.kt | 205 ++++++++++++++++++ .../ui/dialogs/profile/ProfileConfigDialog.kt | 88 ++++++++ .../ProfileRemoveDialog.kt | 6 +- .../dialogs/sync/RegistrationConfigDialog.kt | 10 +- .../ui/modules/debug/LabPageFragment.kt | 2 +- .../modules/settings/SettingsNewFragment.java | 4 +- .../ui/modules/settings/SettingsUtil.kt | 33 +-- .../settings/cards/SettingsProfileCard.kt | 23 +- .../settings/cards/SettingsThemeCard.kt | 56 ++++- .../main/res/layout/dialog_profile_config.xml | 107 +++++++++ .../mal_material_about_profile_item.xml | 2 +- app/src/main/res/values/strings.xml | 3 + 14 files changed, 525 insertions(+), 71 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/MainActivityRequestHandler.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileConfigDialog.kt rename app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/{settings => profile}/ProfileRemoveDialog.kt (95%) create mode 100644 app/src/main/res/layout/dialog_profile_config.xml diff --git a/app/build.gradle b/app/build.gradle index 1766c3bf..15d7cdff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -129,7 +129,7 @@ dependencies { implementation "com.mikepenz:iconics-core:5.2.8" implementation "com.mikepenz:iconics-views:5.2.8" implementation "com.mikepenz:community-material-typeface:5.8.55.0-kotlin@aar" - implementation "eu.szkolny:szkolny-font:1.2" + implementation "eu.szkolny:szkolny-font:1.3" // Other dependencies implementation "cat.ereza:customactivityoncrash:2.3.0" diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 10caf080..971a46d2 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -10,7 +10,6 @@ import android.graphics.BitmapFactory import android.graphics.drawable.BitmapDrawable import android.os.Build import android.os.Bundle -import android.os.Environment import android.provider.Settings import android.view.Gravity import android.view.View @@ -56,7 +55,7 @@ import pl.szczodrzynski.edziennik.ui.dialogs.ServerMessageDialog import pl.szczodrzynski.edziennik.ui.dialogs.UpdateAvailableDialog import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog -import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog +import pl.szczodrzynski.edziennik.ui.dialogs.profile.ProfileRemoveDialog import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment import pl.szczodrzynski.edziennik.ui.modules.announcements.AnnouncementsFragment @@ -98,7 +97,6 @@ import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem import pl.szczodrzynski.navlib.drawer.NavDrawer import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem -import java.io.File import java.io.IOException import java.util.* import kotlin.coroutines.CoroutineContext @@ -111,8 +109,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope { const val TAG = "MainActivity" - const val REQUEST_LOGIN_ACTIVITY = 20222 - const val DRAWER_PROFILE_ADD_NEW = 200 const val DRAWER_PROFILE_SYNC_ALL = 201 const val DRAWER_PROFILE_EXPORT_DATA = 202 @@ -264,6 +260,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { val bottomSheet: NavBottomSheet by lazy { navView.bottomSheet } val mainSnackbar: MainSnackbar by lazy { MainSnackbar(this) } val errorSnackbar: ErrorSnackbar by lazy { ErrorSnackbar(this) } + val requestHandler by lazy { MainActivityRequestHandler(this) } val swipeRefreshLayout: SwipeRefreshLayoutNoTouch by lazy { b.swipeRefreshLayout } @@ -479,28 +476,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { } // APP BACKGROUND - if (app.config.ui.appBackground != null) { - try { - app.config.ui.appBackground?.let { - var bg = it - val bgDir = File(Environment.getExternalStoragePublicDirectory("Szkolny.eu"), "bg") - if (bgDir.exists()) { - val files = bgDir.listFiles() - val r = Random() - val i = r.nextInt(files.size) - bg = files[i].toString() - } - val linearLayout = b.root - if (bg.endsWith(".gif")) { - linearLayout.background = GifDrawable(bg) - } else { - linearLayout.background = BitmapDrawable.createFromPath(bg) - } - } - } catch (e: IOException) { - e.printStackTrace() - } - } + setAppBackground() // IT'S WINTER MY DUDES val today = Date.getToday() @@ -590,7 +566,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { private var profileSettingClickListener = { id: Int, view: View? -> when (id) { DRAWER_PROFILE_ADD_NEW -> { - startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY) + requestHandler.requestLogin() } DRAWER_PROFILE_SYNC_ALL -> { EdziennikTask.sync().enqueue(this) @@ -838,7 +814,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { handleIntent(intent?.extras) } } - private fun handleIntent(extras: Bundle?) { + fun handleIntent(extras: Bundle?) { d(TAG, "handleIntent() {") extras?.keySet()?.forEach { key -> @@ -996,13 +972,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope { } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - if (requestCode == REQUEST_LOGIN_ACTIVITY) { - if (!app.config.loginFinished) - finish() - else { - handleIntent(data?.extras) - } - } + requestHandler.handleResult(requestCode, resultCode, data) } /* _ _ _ _ _ @@ -1228,6 +1198,19 @@ class MainActivity : AppCompatActivity(), CoroutineScope { }, 3000) } + fun setAppBackground() { + try { + b.root.background = app.config.ui.appBackground?.let { + if (it.endsWith(".gif")) + GifDrawable(it) + else + BitmapDrawable.createFromPath(it) + } + } catch (e: IOException) { + e.printStackTrace() + } + } + /* _____ _ _ | __ \ (_) | | | | |_ __ __ ___ _____ _ __ _| |_ ___ _ __ ___ ___ diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivityRequestHandler.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivityRequestHandler.kt new file mode 100644 index 00000000..3f086a44 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivityRequestHandler.kt @@ -0,0 +1,205 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2021-3-23. + */ + +package pl.szczodrzynski.edziennik + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.provider.OpenableColumns +import com.theartofdev.edmodo.cropper.CropImage +import com.theartofdev.edmodo.cropper.CropImageView +import pl.szczodrzynski.edziennik.data.db.entity.Profile +import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity +import java.io.File +import java.io.FileOutputStream + +class MainActivityRequestHandler(val activity: MainActivity) { + companion object { + private const val REQUEST_LOGIN_ACTIVITY = 2000 + private const val REQUEST_FILE_HEADER_BACKGROUND = 3000 + private const val REQUEST_FILE_APP_BACKGROUND = 4000 + private const val REQUEST_FILE_PROFILE_IMAGE = 5000 + private const val REQUEST_CROP_HEADER_BACKGROUND = 3100 + private const val REQUEST_CROP_APP_BACKGROUND = 4100 + private const val REQUEST_CROP_PROFILE_IMAGE = 5100 + } + + private val app = activity.app + private val requestData = mutableMapOf() + private val listeners = mutableMapOf Unit>() + + fun requestLogin() = activity.startActivityForResult( + Intent(activity, LoginActivity::class.java), + REQUEST_LOGIN_ACTIVITY + ) + + fun requestHeaderBackground(listener: (Any?) -> Unit) { + listeners[REQUEST_FILE_HEADER_BACKGROUND] = listener + activity.startActivityForResult( + CropImage.getPickImageChooserIntent( + activity, + activity.getString(R.string.pick_image_intent_chooser_title), + true, + true + ), + REQUEST_FILE_HEADER_BACKGROUND + ) + } + + fun requestAppBackground(listener: (Any?) -> Unit) { + listeners[REQUEST_FILE_APP_BACKGROUND] = listener + activity.startActivityForResult( + CropImage.getPickImageChooserIntent( + activity, + activity.getString(R.string.pick_image_intent_chooser_title), + true, + true + ), + REQUEST_FILE_APP_BACKGROUND + ) + } + + fun requestProfileImage(profile: Profile, listener: (Any?) -> Unit) { + listeners[REQUEST_FILE_PROFILE_IMAGE] = listener + requestData[REQUEST_FILE_PROFILE_IMAGE] = profile + activity.startActivityForResult( + CropImage.getPickImageChooserIntent( + activity, + activity.getString(R.string.pick_image_intent_chooser_title), + true, + true + ), + REQUEST_FILE_PROFILE_IMAGE + ) + } + + private fun getFileInfo(uri: Uri): Pair { + val cursor = activity.contentResolver.query( + uri, + null, + null, + null, + null, + null + ) + + return cursor?.use { + if (it.moveToFirst()) { + val name = it.getString(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) + val mimeIndex = it.getColumnIndex("mime_type") + val mimeType = if (mimeIndex != -1) it.getString(mimeIndex) else null + + name to mimeType + } + else + null + } ?: "unknown" to null + } + + private fun shouldCrop(uri: Uri): Boolean { + val (filename, mimeType) = getFileInfo(uri) + return !filename.endsWith(".gif") && mimeType?.endsWith("/gif") != true + } + + private fun saveFile(uri: Uri, name: String): String { + val (filename, _) = getFileInfo(uri) + val extension = filename.substringAfterLast('.') + val file = File(activity.filesDir, "$name.$extension") + activity.contentResolver.openInputStream(uri)?.use { input -> + FileOutputStream(file).use { output -> + input.copyTo(output) + } + } + return file.absolutePath + } + + fun handleResult(requestCode: Int, resultCode: Int, data: Intent?) { + if (resultCode != Activity.RESULT_OK) + return + var uri = data?.data + when (requestCode) { + REQUEST_LOGIN_ACTIVITY -> { + if (!app.config.loginFinished) + activity.finish() + else { + activity.handleIntent(data?.extras) + } + } + REQUEST_FILE_HEADER_BACKGROUND -> { + if (uri == null) + return // TODO: 2021-03-24 if the app returns no data + if (shouldCrop(uri)) { + val intent = CropImage.activity(uri) + .setAspectRatio(512, 288) + .setGuidelines(CropImageView.Guidelines.ON_TOUCH) + .setAllowFlipping(true) + .setAllowRotation(true) + .setRequestedSize(512, 288) + .getIntent(activity) + activity.startActivityForResult(intent, REQUEST_CROP_HEADER_BACKGROUND) + } else { + val path = saveFile(uri, "header") + app.config.ui.headerBackground = path + listeners.remove(REQUEST_FILE_HEADER_BACKGROUND)?.invoke(path) + } + } + REQUEST_FILE_APP_BACKGROUND -> { + if (uri == null) + return + if (shouldCrop(uri)) { + val intent = CropImage.activity(uri) + .setGuidelines(CropImageView.Guidelines.ON_TOUCH) + .setAllowFlipping(true) + .setAllowRotation(true) + .getIntent(activity) + activity.startActivityForResult(intent, REQUEST_CROP_APP_BACKGROUND) + } else { + val path = saveFile(uri, "background") + app.config.ui.appBackground = path + listeners.remove(REQUEST_FILE_APP_BACKGROUND)?.invoke(path) + } + } + REQUEST_FILE_PROFILE_IMAGE -> { + if (uri == null) + return + if (shouldCrop(uri)) { + val intent = CropImage.activity(uri) + .setAspectRatio(1, 1) + .setCropShape(CropImageView.CropShape.OVAL) + .setGuidelines(CropImageView.Guidelines.ON_TOUCH) + .setAllowFlipping(true) + .setAllowRotation(true) + .setRequestedSize(512, 512) + .getIntent(activity) + activity.startActivityForResult(intent, REQUEST_CROP_PROFILE_IMAGE) + } else { + val profile = requestData.remove(REQUEST_FILE_PROFILE_IMAGE) as? Profile ?: return + val path = saveFile(uri, "profile${profile.id}") + profile.image = path + listeners.remove(REQUEST_FILE_PROFILE_IMAGE)?.invoke(profile) + } + } + REQUEST_CROP_HEADER_BACKGROUND -> { + uri = CropImage.getActivityResult(data)?.uri ?: return + val path = saveFile(uri, "header") + app.config.ui.headerBackground = path + listeners.remove(REQUEST_FILE_HEADER_BACKGROUND)?.invoke(path) + } + REQUEST_CROP_APP_BACKGROUND -> { + uri = CropImage.getActivityResult(data)?.uri ?: return + val path = saveFile(uri, "background") + app.config.ui.appBackground = path + listeners.remove(REQUEST_FILE_APP_BACKGROUND)?.invoke(path) + } + REQUEST_CROP_PROFILE_IMAGE -> { + uri = CropImage.getActivityResult(data)?.uri ?: return + val profile = requestData.remove(REQUEST_FILE_PROFILE_IMAGE) as? Profile ?: return + val path = saveFile(uri, "profile${profile.id}") + profile.image = path + listeners.remove(REQUEST_FILE_PROFILE_IMAGE)?.invoke(profile) + } + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileConfigDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileConfigDialog.kt new file mode 100644 index 00000000..6d51d3a1 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileConfigDialog.kt @@ -0,0 +1,88 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2021-3-23. + */ + +package pl.szczodrzynski.edziennik.ui.dialogs.profile + +import androidx.appcompat.app.AlertDialog +import androidx.core.widget.addTextChangedListener +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import pl.szczodrzynski.edziennik.* +import pl.szczodrzynski.edziennik.data.db.entity.Profile +import pl.szczodrzynski.edziennik.databinding.DialogProfileConfigBinding +import kotlin.coroutines.CoroutineContext + +class ProfileConfigDialog( + val activity: MainActivity, + val profile: Profile, + val onProfileSaved: ((profile: Profile) -> Unit)? = null, + val onShowListener: ((tag: String) -> Unit)? = null, + val onDismissListener: ((tag: String) -> Unit)? = null +) : CoroutineScope { + companion object { + private const val TAG = "ProfileConfigDialog" + } + + private lateinit var app: App + private lateinit var b: DialogProfileConfigBinding + private lateinit var dialog: AlertDialog + + private val job = Job() + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + + // local variables go here + private var profileChanged = false + private var profileRemoved = false + + init { run { + if (activity.isFinishing) + return@run + onShowListener?.invoke(TAG) + app = activity.applicationContext as App + b = DialogProfileConfigBinding.inflate(activity.layoutInflater) + dialog = MaterialAlertDialogBuilder(activity) + .setView(b.root) + .setPositiveButton(R.string.close, null) + .setOnDismissListener { + if (!profileRemoved && profileChanged) { + app.profileSave(profile) + onProfileSaved?.invoke(profile) + } + onDismissListener?.invoke(TAG) + } + .show() + + b.profile = profile + profile.applyImageTo(b.image) + + b.nameEdit.addTextChangedListener { + profileChanged = true + } + + b.syncSwitch.onChange { _, _ -> + profileChanged = true + } + + b.imageButton.onClick { + activity.requestHandler.requestProfileImage(profile) { + val profile = it as? Profile ?: return@requestProfileImage + if (this@ProfileConfigDialog.profile == profile) { + profileChanged = true + b.profile = profile + profile.applyImageTo(b.image) + } + } + } + + b.logoutButton.onClick { + ProfileRemoveDialog(activity, profile.id, profile.name) { + profileRemoved = true + dialog.dismiss() + } + } + }} +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/ProfileRemoveDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileRemoveDialog.kt similarity index 95% rename from app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/ProfileRemoveDialog.kt rename to app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileRemoveDialog.kt index 1fa16230..7071f00d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/settings/ProfileRemoveDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/profile/ProfileRemoveDialog.kt @@ -2,7 +2,7 @@ * Copyright (c) Kuba Szczodrzyński 2019-11-13. */ -package pl.szczodrzynski.edziennik.ui.dialogs.settings +package pl.szczodrzynski.edziennik.ui.dialogs.profile import android.widget.Toast import androidx.appcompat.app.AlertDialog @@ -18,7 +18,8 @@ class ProfileRemoveDialog( val activity: MainActivity, val profileId: Int, val profileName: String, - val noProfileRemoval: Boolean = false + val noProfileRemoval: Boolean = false, + val onRemove: (() -> Unit)? = null ) : CoroutineScope { companion object { private const val TAG = "ProfileRemoveDialog" @@ -95,5 +96,6 @@ class ProfileRemoveDialog( dialog.dismiss() activity.reloadTarget() Toast.makeText(activity, R.string.dialog_profile_remove_success, Toast.LENGTH_LONG).show() + onRemove?.invoke() }} } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/RegistrationConfigDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/RegistrationConfigDialog.kt index 9470534d..fff65b43 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/RegistrationConfigDialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/sync/RegistrationConfigDialog.kt @@ -104,10 +104,12 @@ class RegistrationConfigDialog( // force full registration of the user App.config.getFor(profile.id).hash = "" - AppSync(app, mutableListOf(), listOf(profile), SzkolnyApi(app)).run( - 0L, - markAsSeen = true - ) + SzkolnyApi(app).runCatching(activity) { + AppSync(app, mutableListOf(), listOf(profile), this).run( + 0L, + markAsSeen = true + ) + } app.db.profileDao().add(profile) if (profile.id == App.profileId) { App.profile.registration = profile.registration diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt index 29a0b2b3..b1b84f9d 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/debug/LabPageFragment.kt @@ -16,7 +16,7 @@ import kotlinx.coroutines.launch import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.db.entity.Event import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding -import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog +import pl.szczodrzynski.edziennik.ui.dialogs.profile.ProfileRemoveDialog import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment import pl.szczodrzynski.edziennik.utils.TextInputDropDown import pl.szczodrzynski.fslogin.decode diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsNewFragment.java b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsNewFragment.java index 80aee4dd..a3018097 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsNewFragment.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsNewFragment.java @@ -54,8 +54,8 @@ import pl.szczodrzynski.edziennik.sync.SyncWorker; import pl.szczodrzynski.edziennik.sync.UpdateWorker; import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog; import pl.szczodrzynski.edziennik.ui.dialogs.grade.GradesConfigDialog; +import pl.szczodrzynski.edziennik.ui.dialogs.profile.ProfileRemoveDialog; import pl.szczodrzynski.edziennik.ui.dialogs.settings.AttendanceConfigDialog; -import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog; import pl.szczodrzynski.edziennik.ui.dialogs.sync.NotificationFilterDialog; import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity; import pl.szczodrzynski.edziennik.utils.Themes; @@ -253,7 +253,7 @@ public class SettingsNewFragment extends MaterialAboutFragment { icon(SzkolnyFont.Icon.szf_delete_empty_outline, iconSizeDp, iconColor) ) .setOnClickAction(() -> { - new ProfileRemoveDialog(activity, app.getProfile().getId(), app.getProfile().getName(), false); + new ProfileRemoveDialog(activity, app.getProfile().getId(), app.getProfile().getName(), false, null); }) ); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsUtil.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsUtil.kt index 5ed3fb5d..258f4a17 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsUtil.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/SettingsUtil.kt @@ -4,8 +4,6 @@ package pl.szczodrzynski.edziennik.ui.modules.settings -import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory -import androidx.core.graphics.drawable.toBitmap import com.danielstone.materialaboutlibrary.items.* import com.danielstone.materialaboutlibrary.model.MaterialAboutCard import com.mikepenz.iconics.IconicsDrawable @@ -27,11 +25,12 @@ class SettingsUtil( fun refresh() = onRefresh() - private fun IIcon.asDrawable(color: Int? = null, size: Int = 20) = IconicsDrawable(activity).apply { - icon = this@asDrawable - sizeDp = size - colorInt = color ?: Themes.getPrimaryTextColor(activity) - } + private fun IIcon.asDrawable(color: Int? = null, size: Int = 20) = + IconicsDrawable(activity).apply { + icon = this@asDrawable + sizeDp = size + colorInt = color ?: Themes.getPrimaryTextColor(activity) + } fun createCard( titleRes: Int?, @@ -171,18 +170,20 @@ class SettingsUtil( .icon(R.mipmap.ic_splash) .build() - fun createProfileItem(profile: Profile, onClick: (profile: Profile) -> Unit) = - MaterialAboutProfileItem( + fun createProfileItem( + profile: Profile, + onClick: (item: MaterialAboutProfileItem, profile: Profile) -> Unit + ): MaterialAboutProfileItem { + val item = MaterialAboutProfileItem( MaterialAboutTitleItem.Builder() .text(profile.name) .desc(profile.subname) - .icon(RoundedBitmapDrawableFactory.create( - activity.resources, - profile.getImageDrawable(activity).toBitmap() - ).also { - it.isCircular = true - }) - .setOnClickAction { onClick(profile) } + .icon(profile.getImageDrawable(activity)) .build() ) + item.setOnClickAction { + onClick(item, profile) + } + return item + } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsProfileCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsProfileCard.kt index a783731f..5ac23e62 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsProfileCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsProfileCard.kt @@ -8,8 +8,10 @@ import android.content.Intent import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import eu.szkolny.font.SzkolnyFont import pl.szczodrzynski.edziennik.R -import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog +import pl.szczodrzynski.edziennik.ui.dialogs.profile.ProfileConfigDialog +import pl.szczodrzynski.edziennik.ui.dialogs.profile.ProfileRemoveDialog import pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity +import pl.szczodrzynski.edziennik.ui.modules.settings.MaterialAboutProfileItem import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsCard import pl.szczodrzynski.edziennik.ui.modules.settings.SettingsUtil @@ -21,12 +23,21 @@ class SettingsProfileCard(util: SettingsUtil) : SettingsCard(util) { itemsMore = getItemsMore() ) - override fun getItems() = listOf( - util.createProfileItem( - profile = app.profile - ) { + private fun getProfileItem(): MaterialAboutProfileItem = util.createProfileItem( + profile = app.profile + ) { item, profile -> + ProfileConfigDialog(activity, profile, onProfileSaved = { + val index = card.items.indexOf(item) + if (index == -1) + return@ProfileConfigDialog + card.items.remove(item) + card.items.add(index, getProfileItem()) + util.refresh() + }) + } - }, + override fun getItems() = listOf( + getProfileItem(), util.createActionItem( text = R.string.settings_add_student_text, diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsThemeCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsThemeCard.kt index 0cb710cb..17b108e5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsThemeCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/settings/cards/SettingsThemeCard.kt @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.ui.modules.settings.cards +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.ui.dialogs.settings.AppLanguageDialog @@ -74,7 +75,28 @@ class SettingsThemeCard(util: SettingsUtil) : SettingsCard(util) { text = R.string.settings_theme_drawer_header_text, icon = CommunityMaterial.Icon2.cmd_image_outline ) { - // TODO: 2021-03-17 + if (app.config.ui.appBackground == null) { + setHeaderBackground() + return@createActionItem + } + MaterialAlertDialogBuilder(activity) + .setItems( + arrayOf( + activity.getString(R.string.settings_theme_drawer_header_dialog_set), + activity.getString(R.string.settings_theme_drawer_header_dialog_restore) + ) + ) { _, which -> + when (which) { + 0 -> setHeaderBackground() + 1 -> { + app.config.ui.headerBackground = null + activity.drawer.setAccountHeaderBackground(null) + activity.drawer.open() + } + } + } + .setNegativeButton(R.string.cancel, null) + .show() }, util.createActionItem( @@ -82,7 +104,27 @@ class SettingsThemeCard(util: SettingsUtil) : SettingsCard(util) { subText = R.string.settings_theme_app_background_subtext, icon = CommunityMaterial.Icon2.cmd_image_filter_hdr ) { - // TODO: 2021-03-17 + if (app.config.ui.appBackground == null) { + setAppBackground() + return@createActionItem + } + MaterialAlertDialogBuilder(activity) + .setItems( + arrayOf( + activity.getString(R.string.settings_theme_app_background_dialog_set), + activity.getString(R.string.settings_theme_app_background_dialog_restore) + ) + ) { _, which -> + when (which) { + 0 -> setAppBackground() + 1 -> { + app.config.ui.appBackground = null + activity.setAppBackground() + } + } + } + .setNegativeButton(R.string.cancel, null) + .show() }, util.createPropertyItem( @@ -93,4 +135,14 @@ class SettingsThemeCard(util: SettingsUtil) : SettingsCard(util) { configGlobal.ui.openDrawerOnBackPressed = it } ) + + private fun setHeaderBackground() = activity.requestHandler.requestHeaderBackground { + activity.drawer.setAccountHeaderBackground(null) + activity.drawer.setAccountHeaderBackground(app.config.ui.headerBackground) + activity.drawer.open() + } + + private fun setAppBackground() = activity.requestHandler.requestAppBackground { + activity.setAppBackground() + } } diff --git a/app/src/main/res/layout/dialog_profile_config.xml b/app/src/main/res/layout/dialog_profile_config.xml new file mode 100644 index 00000000..e83af680 --- /dev/null +++ b/app/src/main/res/layout/dialog_profile_config.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/mal_material_about_profile_item.xml b/app/src/main/res/layout/mal_material_about_profile_item.xml index e1802130..4b94b21e 100644 --- a/app/src/main/res/layout/mal_material_about_profile_item.xml +++ b/app/src/main/res/layout/mal_material_about_profile_item.xml @@ -6,7 +6,7 @@ android:orientation="horizontal" android:paddingHorizontal="@dimen/mal_baseline_half"> - Uzyskaj pomoc lub wesprzyj autorów Kod źródłowy Pomóż w rozwoju aplikacji na GitHubie + Nazwa profilu + Synchronizuj ten profil + Wyloguj się