diff --git a/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt b/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt index 3b5d8518f1..bac98a2281 100644 --- a/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/AccountsInListFragment.kt @@ -16,6 +16,7 @@ package com.keylesspalace.tusky +import android.app.Dialog import android.content.SharedPreferences import android.os.Bundle import android.view.LayoutInflater @@ -29,6 +30,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.ListAdapter +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.keylesspalace.tusky.databinding.FragmentAccountsInListBinding import com.keylesspalace.tusky.databinding.ItemFollowRequestBinding import com.keylesspalace.tusky.entity.TimelineAccount @@ -39,7 +41,6 @@ import com.keylesspalace.tusky.util.hide import com.keylesspalace.tusky.util.loadAvatar import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.unsafeLazy -import com.keylesspalace.tusky.util.viewBinding import com.keylesspalace.tusky.util.visible import com.keylesspalace.tusky.viewmodel.AccountsInListViewModel import com.keylesspalace.tusky.viewmodel.State @@ -50,13 +51,13 @@ import kotlinx.coroutines.launch private typealias AccountInfo = Pair @AndroidEntryPoint -class AccountsInListFragment : DialogFragment(R.layout.fragment_accounts_in_list) { +class AccountsInListFragment : DialogFragment() { @Inject lateinit var preferences: SharedPreferences private val viewModel: AccountsInListViewModel by viewModels() - private val binding by viewBinding(FragmentAccountsInListBinding::bind) + private lateinit var binding: FragmentAccountsInListBinding private lateinit var listId: String private lateinit var listName: String @@ -65,7 +66,6 @@ class AccountsInListFragment : DialogFragment(R.layout.fragment_accounts_in_list override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, R.style.TuskyDialogFragmentStyle) val args = requireArguments() listId = args.getString(LIST_ID_ARG)!! listName = args.getString(LIST_NAME_ARG)!! @@ -73,6 +73,12 @@ class AccountsInListFragment : DialogFragment(R.layout.fragment_accounts_in_list viewModel.load(listId) } + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + return MaterialAlertDialogBuilder(requireContext()) + .setView(createView()) + .create() + } + override fun onStart() { super.onStart() dialog?.apply { @@ -84,17 +90,18 @@ class AccountsInListFragment : DialogFragment(R.layout.fragment_accounts_in_list } } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + private fun createView(): View { + binding = FragmentAccountsInListBinding.inflate(layoutInflater) val adapter = Adapter() val searchAdapter = SearchAdapter() - binding.accountsRecycler.layoutManager = LinearLayoutManager(view.context) + binding.accountsRecycler.layoutManager = LinearLayoutManager(binding.root.context) binding.accountsRecycler.adapter = adapter - binding.accountsSearchRecycler.layoutManager = LinearLayoutManager(view.context) + binding.accountsSearchRecycler.layoutManager = LinearLayoutManager(binding.root.context) binding.accountsSearchRecycler.adapter = searchAdapter - viewLifecycleOwner.lifecycleScope.launch { + lifecycleScope.launch { viewModel.state.collect { state -> adapter.submitList(state.accounts.getOrDefault(emptyList())) @@ -122,6 +129,7 @@ class AccountsInListFragment : DialogFragment(R.layout.fragment_accounts_in_list return true } }) + return binding.root } private fun setupSearchView(searchAdapter: SearchAdapter, state: State) { diff --git a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt index 7cd0b8eacd..e7ab6c75c1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/TabPreferenceActivity.kt @@ -19,11 +19,8 @@ import android.graphics.Color import android.os.Bundle import android.view.View import android.view.WindowManager -import android.widget.FrameLayout import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AlertDialog -import androidx.appcompat.widget.AppCompatEditText -import androidx.core.view.updatePadding import androidx.core.widget.doOnTextChanged import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.DividerItemDecoration @@ -31,7 +28,6 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import androidx.transition.TransitionManager -import at.connyduck.sparkbutton.helpers.Utils import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.transition.MaterialArcMotion import com.google.android.material.transition.MaterialContainerTransform @@ -41,6 +37,7 @@ import com.keylesspalace.tusky.appstore.EventHub import com.keylesspalace.tusky.appstore.MainTabsChangedEvent import com.keylesspalace.tusky.components.account.list.ListSelectionFragment import com.keylesspalace.tusky.databinding.ActivityTabPreferenceBinding +import com.keylesspalace.tusky.databinding.DialogAddHashtagBinding import com.keylesspalace.tusky.entity.MastoList import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.unsafeLazy @@ -231,18 +228,12 @@ class TabPreferenceActivity : BaseActivity(), ItemInteractionListener, ListSelec } private fun showAddHashtagDialog(tab: TabData? = null, tabPosition: Int = 0) { - val frameLayout = FrameLayout(this) - val padding = Utils.dpToPx(this, 8) - frameLayout.updatePadding(left = padding, right = padding) - - val editText = AppCompatEditText(this) - editText.setHint(R.string.edit_hashtag_hint) - editText.setText("") - frameLayout.addView(editText) + val dialogBinding = DialogAddHashtagBinding.inflate(layoutInflater) + val editText = dialogBinding.addHashtagEditText val dialog = MaterialAlertDialogBuilder(this) .setTitle(R.string.add_hashtag_title) - .setView(frameLayout) + .setView(dialogBinding.root) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.action_save) { _, _ -> val input = editText.text.toString().trim() diff --git a/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt index 3837714969..bfa15b7377 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/account/list/ListSelectionFragment.kt @@ -66,7 +66,6 @@ class ListSelectionFragment : DialogFragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, R.style.TuskyDialogFragmentStyle) accountId = requireArguments().getString(ARG_ACCOUNT_ID) } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/compose/dialog/CaptionDialog.kt b/app/src/main/java/com/keylesspalace/tusky/components/compose/dialog/CaptionDialog.kt index 7b987ee999..5c20200b72 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/compose/dialog/CaptionDialog.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/compose/dialog/CaptionDialog.kt @@ -15,15 +15,14 @@ package com.keylesspalace.tusky.components.compose.dialog +import android.app.Dialog import android.content.Context import android.graphics.drawable.Animatable import android.graphics.drawable.Drawable import android.net.Uri import android.os.Bundle import android.text.InputFilter -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import android.view.WindowManager import android.widget.LinearLayout import androidx.core.os.bundleOf @@ -32,11 +31,11 @@ import com.bumptech.glide.Glide import com.bumptech.glide.load.resource.bitmap.DownsampleStrategy import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.keylesspalace.tusky.R import com.keylesspalace.tusky.databinding.DialogImageDescriptionBinding import com.keylesspalace.tusky.util.getParcelableCompat import com.keylesspalace.tusky.util.hide -import com.keylesspalace.tusky.util.viewBinding // https://github.com/tootsuite/mastodon/blob/c6904c0d3766a2ea8a81ab025c127169ecb51373/app/models/media_attachment.rb#L32 private const val MEDIA_DESCRIPTION_CHARACTER_LIMIT = 1500 @@ -44,22 +43,23 @@ private const val MEDIA_DESCRIPTION_CHARACTER_LIMIT = 1500 class CaptionDialog : DialogFragment() { private lateinit var listener: Listener - private val binding by viewBinding(DialogImageDescriptionBinding::bind) + private lateinit var binding: DialogImageDescriptionBinding private var animatable: Animatable? = null - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setStyle(STYLE_NORMAL, R.style.TuskyDialogFragmentStyle) + override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { + val localId = arguments?.getInt(LOCAL_ID_ARG) ?: error("Missing localId") + return MaterialAlertDialogBuilder(requireContext()) + .setView(createView(savedInstanceState)) + .setPositiveButton(android.R.string.ok) { _, _ -> + listener.onUpdateDescription(localId, binding.imageDescriptionText.text.toString()) + } + .setNegativeButton(android.R.string.cancel, null) + .create() } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View = inflater.inflate(R.layout.dialog_image_description, container, false) - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + private fun createView(savedInstanceState: Bundle?): View { + binding = DialogImageDescriptionBinding.inflate(layoutInflater) val imageView = binding.imageDescriptionView imageView.maxZoom = 6f val imageDescriptionText = binding.imageDescriptionText @@ -79,15 +79,6 @@ class CaptionDialog : DialogFragment() { binding.imageDescriptionText.setText(it) } - binding.cancelButton.setOnClickListener { - dismiss() - } - val localId = arguments?.getInt(LOCAL_ID_ARG) ?: error("Missing localId") - binding.okButton.setOnClickListener { - listener.onUpdateDescription(localId, binding.imageDescriptionText.text.toString()) - dismiss() - } - isCancelable = true dialog?.setCanceledOnTouchOutside(false) // Dialog is full screen anyway. But without this, taps in navbar while keyboard is up can dismiss the dialog. @@ -109,15 +100,15 @@ class CaptionDialog : DialogFragment() { if (resource is Animatable) { resource.callback = object : Drawable.Callback { override fun invalidateDrawable(who: Drawable) { - view.invalidate() + imageView.invalidate() } override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) { - view.postDelayed(what, `when`) + imageView.postDelayed(what, `when`) } override fun unscheduleDrawable(who: Drawable, what: Runnable) { - view.removeCallbacks(what) + imageView.removeCallbacks(what) } } resource.start() @@ -131,6 +122,7 @@ class CaptionDialog : DialogFragment() { imageView.hide() } }) + return binding.root } override fun onStart() { diff --git a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt index ca50fdb27c..ba0d327aeb 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/followedtags/FollowedTagsActivity.kt @@ -1,14 +1,10 @@ package com.keylesspalace.tusky.components.followedtags -import android.app.Dialog -import android.content.DialogInterface import android.content.SharedPreferences import android.os.Bundle import android.util.Log import android.view.WindowManager -import android.widget.AutoCompleteTextView import androidx.activity.viewModels -import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.paging.LoadState import androidx.recyclerview.widget.DividerItemDecoration @@ -22,6 +18,7 @@ import com.keylesspalace.tusky.R import com.keylesspalace.tusky.StatusListActivity import com.keylesspalace.tusky.components.compose.ComposeAutoCompleteAdapter import com.keylesspalace.tusky.databinding.ActivityFollowedTagsBinding +import com.keylesspalace.tusky.databinding.DialogFollowHashtagBinding import com.keylesspalace.tusky.interfaces.HashtagActionListener import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.util.copyToClipboard @@ -61,8 +58,7 @@ class FollowedTagsActivity : } binding.fab.setOnClickListener { - val dialog: DialogFragment = FollowTagDialog.newInstance() - dialog.show(supportFragmentManager, "dialog") + showDialog() } setupAdapter().let { adapter -> @@ -179,44 +175,34 @@ class FollowedTagsActivity : ) } - companion object { - const val TAG = "FollowedTagsActivity" - } - - class FollowTagDialog : DialogFragment() { - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val layout = layoutInflater.inflate(R.layout.dialog_follow_hashtag, null) - val autoCompleteTextView = layout.findViewById(R.id.hashtag)!! - autoCompleteTextView.setAdapter( - ComposeAutoCompleteAdapter( - requireActivity() as FollowedTagsActivity, - animateAvatar = false, - animateEmojis = false, - showBotBadge = false - ) + private fun showDialog() { + val dialogBinding = DialogFollowHashtagBinding.inflate(layoutInflater) + dialogBinding.hashtagAutoCompleteTextView.setAdapter( + ComposeAutoCompleteAdapter( + this, + animateAvatar = false, + animateEmojis = false, + showBotBadge = false ) - autoCompleteTextView.requestFocus() - autoCompleteTextView.setSelection(autoCompleteTextView.length()) - - return MaterialAlertDialogBuilder(requireActivity()) - .setTitle(R.string.dialog_follow_hashtag_title) - .setView(layout) - .setPositiveButton(android.R.string.ok) { _, _ -> - (requireActivity() as FollowedTagsActivity).follow( - autoCompleteTextView.text.toString().removePrefix("#") - ) - } - .setNegativeButton(android.R.string.cancel) { _: DialogInterface, _: Int -> } - .create() - } - - override fun onStart() { - super.onStart() - dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - } + ) + dialogBinding.hashtagAutoCompleteTextView.requestFocus() + dialogBinding.hashtagAutoCompleteTextView.setSelection(dialogBinding.hashtagAutoCompleteTextView.length()) + + val dialog = MaterialAlertDialogBuilder(this) + .setTitle(R.string.dialog_follow_hashtag_title) + .setView(dialogBinding.root) + .setPositiveButton(android.R.string.ok) { _, _ -> + follow( + dialogBinding.hashtagAutoCompleteTextView.text.toString().removePrefix("#") + ) + } + .setNegativeButton(android.R.string.cancel, null) + .create() + dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + dialog.show() + } - companion object { - fun newInstance(): FollowTagDialog = FollowTagDialog() - } + companion object { + const val TAG = "FollowedTagsActivity" } } diff --git a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt index c2001422d7..089f66b628 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/notifications/NotificationsFragment.kt @@ -433,7 +433,7 @@ class NotificationsFragment : } val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_list_item_multiple_choice, notificationTypeList) - val window = PopupWindow(requireContext()) + val window = PopupWindow(requireContext(), null, com.google.android.material.R.attr.listPopupWindowStyle) val menuBinding = NotificationsFilterBinding.inflate(LayoutInflater.from(requireContext()), binding.root as ViewGroup, false) menuBinding.buttonApply.setOnClickListener { diff --git a/app/src/main/java/com/keylesspalace/tusky/view/BackgroundMessageView.kt b/app/src/main/java/com/keylesspalace/tusky/view/BackgroundMessageView.kt index c33533628f..56492853eb 100644 --- a/app/src/main/java/com/keylesspalace/tusky/view/BackgroundMessageView.kt +++ b/app/src/main/java/com/keylesspalace/tusky/view/BackgroundMessageView.kt @@ -15,6 +15,8 @@ import com.keylesspalace.tusky.databinding.ViewBackgroundMessageBinding import com.keylesspalace.tusky.util.addDrawables import com.keylesspalace.tusky.util.getDrawableRes import com.keylesspalace.tusky.util.getErrorString +import com.keylesspalace.tusky.util.hide +import com.keylesspalace.tusky.util.show import com.keylesspalace.tusky.util.visible /** @@ -61,7 +63,7 @@ class BackgroundMessageView @JvmOverloads constructor( binding.imageView.setImageResource(imageRes) binding.button.setOnClickListener(clickListener) binding.button.visible(clickListener != null) - binding.helpText.visible(false) + binding.helpTextCard.hide() } fun showHelp(@StringRes helpRes: Int) { @@ -72,6 +74,6 @@ class BackgroundMessageView @JvmOverloads constructor( binding.helpText.setText(textWithDrawables, TextView.BufferType.SPANNABLE) - binding.helpText.visible(true) + binding.helpTextCard.show() } } diff --git a/app/src/main/res/drawable/help_message_background.xml b/app/src/main/res/drawable/help_message_background.xml deleted file mode 100644 index cb28b79870..0000000000 --- a/app/src/main/res/drawable/help_message_background.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 64efada860..cd54159277 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -34,6 +34,8 @@ android:layout_height="48dp" android:orientation="horizontal" app:contentInsetStart="0dp" + android:paddingLeft="0dp" + android:paddingRight="0dp" app:contentInsetStartWithNavigation="0dp" app:navigationContentDescription="@string/action_open_drawer"> diff --git a/app/src/main/res/layout/dialog_add_hashtag.xml b/app/src/main/res/layout/dialog_add_hashtag.xml new file mode 100644 index 0000000000..799a1fb26b --- /dev/null +++ b/app/src/main/res/layout/dialog_add_hashtag.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_filter.xml b/app/src/main/res/layout/dialog_filter.xml index 376167d9ad..ee91bbb29c 100644 --- a/app/src/main/res/layout/dialog_filter.xml +++ b/app/src/main/res/layout/dialog_filter.xml @@ -1,34 +1,43 @@ - + android:paddingLeft="20dp" + android:paddingTop="16dp" + android:paddingRight="20dp"> - + app:layout_constraintTop_toTopOf="parent"> + + + + + + app:layout_constraintTop_toBottomOf="@id/phraseInputLayout" /> + - \ No newline at end of file + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintTop_toBottomOf="@id/phraseWholeWord" /> + + diff --git a/app/src/main/res/layout/dialog_follow_hashtag.xml b/app/src/main/res/layout/dialog_follow_hashtag.xml index cdcf3024bf..dca465eaf5 100644 --- a/app/src/main/res/layout/dialog_follow_hashtag.xml +++ b/app/src/main/res/layout/dialog_follow_hashtag.xml @@ -1,16 +1,28 @@ + android:layout_height="wrap_content" + android:paddingLeft="20dp" + android:paddingTop="16dp" + android:paddingRight="20dp"> - - + android:hint="@string/dialog_follow_hashtag_hint" + app:endIconMode="none"> + + + + + diff --git a/app/src/main/res/layout/dialog_image_description.xml b/app/src/main/res/layout/dialog_image_description.xml index e44b4887ea..75e278f810 100644 --- a/app/src/main/res/layout/dialog_image_description.xml +++ b/app/src/main/res/layout/dialog_image_description.xml @@ -1,5 +1,4 @@ - - - -