mirror of
https://github.com/accelforce/Yuito
synced 2025-02-01 16:36:50 +01:00
Refactor quick compose
* Stash visibility while composing reply * Remove announcements
This commit is contained in:
parent
bb5106a18d
commit
025ba68df4
@ -34,10 +34,10 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
@ -65,6 +65,7 @@ import com.keylesspalace.tusky.components.preference.PreferencesActivity
|
||||
import com.keylesspalace.tusky.components.scheduled.ScheduledTootActivity
|
||||
import com.keylesspalace.tusky.components.search.SearchActivity
|
||||
import com.keylesspalace.tusky.db.AccountEntity
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.entity.Account
|
||||
import com.keylesspalace.tusky.fragment.NotificationsFragment
|
||||
import com.keylesspalace.tusky.fragment.SFragment
|
||||
@ -94,7 +95,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import net.accelf.yuito.FooterDrawerItem
|
||||
import net.accelf.yuito.QuickTootHelper
|
||||
import net.accelf.yuito.QuickTootViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInjector {
|
||||
@ -110,6 +111,11 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||
@Inject
|
||||
lateinit var conversationRepository: ConversationsRepository
|
||||
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
|
||||
private val quickTootViewModel: QuickTootViewModel by viewModels { viewModelFactory }
|
||||
|
||||
private lateinit var header: AccountHeaderView
|
||||
|
||||
private var streamingTabsCount = 0
|
||||
@ -182,10 +188,8 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||
window.statusBarColor = Color.TRANSPARENT // don't draw a status bar, the DrawerLayout and the MaterialDrawerLayout have their own
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
val quickTootHelper = QuickTootHelper(this, quickTootContainer as ConstraintLayout?, accountManager, eventHub)
|
||||
composeButton.setOnClickListener {
|
||||
quickTootHelper.composeButton()
|
||||
}
|
||||
viewQuickToot.attachViewModel(quickTootViewModel, this)
|
||||
composeButton.setOnClickListener(viewQuickToot::onFABClicked)
|
||||
|
||||
val hideTopToolbar = preferences.getBoolean(PrefKeys.HIDE_TOP_TOOLBAR, false)
|
||||
mainToolbar.visible(!hideTopToolbar)
|
||||
@ -238,7 +242,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||
is ProfileEditedEvent -> onFetchUserInfoSuccess(event.newProfileData)
|
||||
is MainTabsChangedEvent -> setupTabs(false)
|
||||
}
|
||||
quickTootHelper.handleEvent(event)
|
||||
viewQuickToot.handleEvent(event)
|
||||
}
|
||||
|
||||
// Flush old media that was cached for sharing
|
||||
@ -475,7 +479,6 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||
)
|
||||
addStickyDrawerItems(
|
||||
FooterDrawerItem().apply {
|
||||
eventHub = this@MainActivity.eventHub
|
||||
setSubscribeProxy(
|
||||
mastodonApi.getInstance()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
|
@ -4,10 +4,11 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.activity.viewModels
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment
|
||||
import com.keylesspalace.tusky.interfaces.ActionButtonActivity
|
||||
import com.uber.autodispose.AutoDispose.autoDisposable
|
||||
@ -15,8 +16,10 @@ import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider.from
|
||||
import dagger.android.DispatchingAndroidInjector
|
||||
import dagger.android.HasAndroidInjector
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.activity_main.viewQuickToot
|
||||
import kotlinx.android.synthetic.main.activity_modal_timeline.*
|
||||
import kotlinx.android.synthetic.main.toolbar_basic.*
|
||||
import net.accelf.yuito.QuickTootHelper
|
||||
import net.accelf.yuito.QuickTootViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class ModalTimelineActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInjector {
|
||||
@ -40,6 +43,10 @@ class ModalTimelineActivity : BottomSheetActivity(), ActionButtonActivity, HasAn
|
||||
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
|
||||
@Inject
|
||||
lateinit var eventHub: EventHub
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
|
||||
private val quickTootViewModel: QuickTootViewModel by viewModels { viewModelFactory }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -62,15 +69,13 @@ class ModalTimelineActivity : BottomSheetActivity(), ActionButtonActivity, HasAn
|
||||
.commit()
|
||||
}
|
||||
|
||||
val quickTootContainer = findViewById<ConstraintLayout>(R.id.quick_toot_container)
|
||||
val composeButton = findViewById<FloatingActionButton>(R.id.floating_btn)
|
||||
val quickTootHelper = QuickTootHelper(this, quickTootContainer, accountManager, eventHub)
|
||||
viewQuickToot.attachViewModel(quickTootViewModel, this)
|
||||
|
||||
eventHub.events
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.`as`(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY)))
|
||||
.subscribe(quickTootHelper::handleEvent)
|
||||
composeButton.setOnClickListener { quickTootHelper.composeButton() }
|
||||
.subscribe(viewQuickToot::handleEvent)
|
||||
floating_btn.setOnClickListener(viewQuickToot::onFABClicked)
|
||||
}
|
||||
|
||||
override fun getActionButton(): FloatingActionButton? = null
|
||||
|
@ -19,11 +19,11 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.activity.viewModels
|
||||
import androidx.fragment.app.commit
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment.Kind
|
||||
import com.uber.autodispose.AutoDispose
|
||||
@ -33,8 +33,9 @@ import dagger.android.HasAndroidInjector
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.extensions.CacheImplementation
|
||||
import kotlinx.android.extensions.ContainerOptions
|
||||
import kotlinx.android.synthetic.main.activity_statuslist.*
|
||||
import kotlinx.android.synthetic.main.toolbar_basic.*
|
||||
import net.accelf.yuito.QuickTootHelper
|
||||
import net.accelf.yuito.QuickTootViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
||||
@ -43,6 +44,10 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
||||
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>
|
||||
@Inject
|
||||
lateinit var eventHub: EventHub
|
||||
@Inject
|
||||
lateinit var viewModelFactory: ViewModelFactory
|
||||
|
||||
private val quickTootViewModel: QuickTootViewModel by viewModels{ viewModelFactory }
|
||||
|
||||
private val kind: Kind
|
||||
get() = Kind.valueOf(intent.getStringExtra(EXTRA_KIND)!!)
|
||||
@ -71,16 +76,13 @@ class StatusListActivity : BottomSheetActivity(), HasAndroidInjector {
|
||||
replace(R.id.fragment_container, fragment)
|
||||
}
|
||||
|
||||
val quickTootContainer = findViewById<ConstraintLayout>(R.id.quick_toot_container)
|
||||
val composeButton = findViewById<FloatingActionButton>(R.id.floating_btn)
|
||||
val quickTootHelper = QuickTootHelper(this, quickTootContainer, accountManager, eventHub)
|
||||
viewQuickToot.attachViewModel(quickTootViewModel, this)
|
||||
|
||||
eventHub.events
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.`as`(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this, Lifecycle.Event.ON_DESTROY)))
|
||||
.subscribe(quickTootHelper::handleEvent)
|
||||
composeButton.setOnClickListener { quickTootHelper.composeButton() }
|
||||
|
||||
.subscribe(viewQuickToot::handleEvent)
|
||||
floating_btn.setOnClickListener(viewQuickToot::onFABClicked)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -23,15 +23,16 @@ import android.view.MenuItem;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
import com.keylesspalace.tusky.appstore.EventHub;
|
||||
import com.keylesspalace.tusky.di.ViewModelFactory;
|
||||
import com.keylesspalace.tusky.fragment.TimelineFragment;
|
||||
|
||||
import net.accelf.yuito.QuickTootHelper;
|
||||
import net.accelf.yuito.QuickTootView;
|
||||
import net.accelf.yuito.QuickTootViewModel;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@ -53,6 +54,8 @@ public class ViewTagActivity extends BottomSheetActivity implements HasAndroidIn
|
||||
public DispatchingAndroidInjector<Object> dispatchingAndroidInjector;
|
||||
@Inject
|
||||
public EventHub eventHub;
|
||||
@Inject
|
||||
public ViewModelFactory viewModelFactory;
|
||||
|
||||
public static Intent getIntent(Context context, String tag){
|
||||
Intent intent = new Intent(context,ViewTagActivity.class);
|
||||
@ -82,13 +85,14 @@ public class ViewTagActivity extends BottomSheetActivity implements HasAndroidIn
|
||||
fragmentTransaction.replace(R.id.fragment_container, fragment);
|
||||
fragmentTransaction.commit();
|
||||
|
||||
ConstraintLayout quickTootContainer = findViewById(R.id.quick_toot_container);
|
||||
QuickTootHelper quickTootHelper = new QuickTootHelper(this, quickTootContainer, accountManager, eventHub);
|
||||
QuickTootViewModel quickTootViewModel = viewModelFactory.create(QuickTootViewModel.class);
|
||||
QuickTootView quickTootView = findViewById(R.id.viewQuickToot);
|
||||
quickTootView.attachViewModel(quickTootViewModel, this);
|
||||
|
||||
eventHub.getEvents()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.as(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY)))
|
||||
.subscribe(quickTootHelper::handleEvent);
|
||||
.subscribe(quickTootView::handleEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,4 +23,3 @@ data class PollVoteEvent(val statusId: String, val poll: Poll) : Dispatchable
|
||||
data class DomainMuteEvent(val instance: String): Dispatchable
|
||||
data class QuickReplyEvent(val status: Status) : Dispatchable
|
||||
data class StreamUpdateEvent(val status: Status, val targetKind: TimelineFragment.Kind, val targetIdentifier: String?, val first: Boolean) : Dispatchable
|
||||
data class DrawerFooterClickedEvent(val placeholder: Boolean) : Dispatchable
|
@ -17,6 +17,7 @@ import dagger.Binds
|
||||
import dagger.MapKey
|
||||
import dagger.Module
|
||||
import dagger.multibindings.IntoMap
|
||||
import net.accelf.yuito.QuickTootViewModel
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
import javax.inject.Singleton
|
||||
@ -85,5 +86,10 @@ abstract class ViewModelModule {
|
||||
@ViewModelKey(ScheduledTootViewModel::class)
|
||||
internal abstract fun scheduledTootViewModel(viewModel: ScheduledTootViewModel): ViewModel
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(QuickTootViewModel::class)
|
||||
internal abstract fun quickTootViewModel(viewModel: QuickTootViewModel): ViewModel
|
||||
|
||||
//Add more ViewModels here
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
package com.keylesspalace.tusky.entity
|
||||
|
||||
import android.text.Spanned
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import java.util.*
|
||||
|
||||
data class Announcement(
|
||||
val id: String,
|
||||
val content: Spanned,
|
||||
@SerializedName("starts_at") val startsAt: Date,
|
||||
@SerializedName("ends_at") val endsAt: Date,
|
||||
@SerializedName("all_day") val allDay: Boolean,
|
||||
val emojis: List<Emoji>,
|
||||
val mentions: Array<Status.Mention>
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
||||
val announcement = other as Announcement?
|
||||
return id == announcement?.id
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id.hashCode()
|
||||
}
|
||||
}
|
@ -505,9 +505,6 @@ interface MastodonApi {
|
||||
@Field("choices[]") choices: List<Int>
|
||||
): Single<Poll>
|
||||
|
||||
@GET("api/v1/announcements")
|
||||
fun listAnnouncements(): Single<List<Announcement>>
|
||||
|
||||
@POST("api/v1/accounts/{id}/block")
|
||||
fun blockAccountObservable(
|
||||
@Path("id") accountId: String
|
||||
|
@ -5,20 +5,15 @@ import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.appstore.DrawerFooterClickedEvent
|
||||
import com.keylesspalace.tusky.appstore.EventHub
|
||||
import com.keylesspalace.tusky.entity.Instance
|
||||
import com.mikepenz.materialdrawer.model.AbstractDrawerItem
|
||||
import com.uber.autodispose.SingleSubscribeProxy
|
||||
import kotlinx.android.synthetic.main.item_drawer_footer.view.*
|
||||
|
||||
class FooterDrawerItem : AbstractDrawerItem<FooterDrawerItem, FooterDrawerItem.ViewHolder>() {
|
||||
override val type: Int
|
||||
get() = R.id.instanceData
|
||||
override val type = R.id.instanceData
|
||||
|
||||
override val layoutRes: Int
|
||||
get() = R.layout.item_drawer_footer
|
||||
|
||||
lateinit var eventHub: EventHub
|
||||
override val layoutRes = R.layout.item_drawer_footer
|
||||
|
||||
private lateinit var context: Context
|
||||
private lateinit var instanceData: TextView
|
||||
@ -29,24 +24,9 @@ class FooterDrawerItem : AbstractDrawerItem<FooterDrawerItem, FooterDrawerItem.V
|
||||
instanceData = holder.instanceData
|
||||
holder.itemView.setPadding(0, 0, 0, 0)
|
||||
instanceData.setTextColor(instanceData.hintTextColors)
|
||||
onDrawerItemClickListener = { _, _, _ ->
|
||||
var result = true
|
||||
var text = instanceData.text.toString()
|
||||
text += "?"
|
||||
if (text.endsWith("???????")) {
|
||||
text = text.substring(0, text.length - 7)
|
||||
eventHub.dispatch(DrawerFooterClickedEvent(true))
|
||||
isExpanded = false
|
||||
result = false
|
||||
}
|
||||
instanceData.text = text
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewHolder(v: View): ViewHolder {
|
||||
return ViewHolder(v)
|
||||
}
|
||||
override fun getViewHolder(v: View) = ViewHolder(v)
|
||||
|
||||
fun setSubscribeProxy(subscribeProxy: SingleSubscribeProxy<Instance>) {
|
||||
subscribeProxy.subscribe(
|
||||
@ -60,6 +40,6 @@ class FooterDrawerItem : AbstractDrawerItem<FooterDrawerItem, FooterDrawerItem.V
|
||||
}
|
||||
|
||||
class ViewHolder internal constructor(internal val view: View): RecyclerView.ViewHolder(view) {
|
||||
internal val instanceData: TextView = view.findViewById(R.id.instanceData)
|
||||
internal val instanceData = view.instanceData
|
||||
}
|
||||
}
|
||||
|
@ -1,346 +0,0 @@
|
||||
package net.accelf.yuito;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
||||
import com.keylesspalace.tusky.AccountActivity;
|
||||
import com.keylesspalace.tusky.BottomSheetActivity;
|
||||
import com.keylesspalace.tusky.PostLookupFallbackBehavior;
|
||||
import com.keylesspalace.tusky.R;
|
||||
import com.keylesspalace.tusky.ViewTagActivity;
|
||||
import com.keylesspalace.tusky.appstore.DrawerFooterClickedEvent;
|
||||
import com.keylesspalace.tusky.appstore.Event;
|
||||
import com.keylesspalace.tusky.appstore.EventHub;
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent;
|
||||
import com.keylesspalace.tusky.appstore.QuickReplyEvent;
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity;
|
||||
import com.keylesspalace.tusky.components.compose.view.TootButton;
|
||||
import com.keylesspalace.tusky.db.AccountEntity;
|
||||
import com.keylesspalace.tusky.db.AccountManager;
|
||||
import com.keylesspalace.tusky.entity.Announcement;
|
||||
import com.keylesspalace.tusky.entity.Status;
|
||||
import com.keylesspalace.tusky.interfaces.LinkListener;
|
||||
import com.keylesspalace.tusky.util.LinkHelper;
|
||||
import com.keylesspalace.tusky.util.ListUtils;
|
||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
|
||||
import static com.keylesspalace.tusky.components.compose.ComposeActivity.CAN_USE_UNLEAKABLE;
|
||||
import static com.keylesspalace.tusky.components.compose.ComposeActivity.PREF_DEFAULT_TAG;
|
||||
import static com.keylesspalace.tusky.components.compose.ComposeActivity.PREF_USE_DEFAULT_TAG;
|
||||
import static com.uber.autodispose.AutoDispose.autoDisposable;
|
||||
import static com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider.from;
|
||||
|
||||
public class QuickTootHelper {
|
||||
|
||||
private Context context;
|
||||
private TextView quickReplyInfo;
|
||||
private TextView defaultTagInfo;
|
||||
private ImageView visibilityButton;
|
||||
private EditText tootEditText;
|
||||
private ImageButton openAnnouncementsButton;
|
||||
private TextView announcementsText;
|
||||
private ImageButton prevButton;
|
||||
private ImageButton nextButton;
|
||||
private TextView announcementsCountText;
|
||||
private TootButton quickTootButton;
|
||||
|
||||
private SharedPreferences defPrefs;
|
||||
private String domain;
|
||||
private String loggedInUsername;
|
||||
private EventHub eventHub;
|
||||
private LinkListener listener;
|
||||
|
||||
private Status inReplyTo;
|
||||
private boolean open = false;
|
||||
private int index = 0;
|
||||
private List<Announcement> announcements;
|
||||
|
||||
private static final String PREF_CURRENT_VISIBILITY = "current_visibility";
|
||||
|
||||
public QuickTootHelper(BottomSheetActivity activity, ConstraintLayout root, AccountManager accountManager, EventHub eventHub) {
|
||||
context = root.getContext();
|
||||
quickReplyInfo = root.findViewById(R.id.quick_reply_info);
|
||||
defaultTagInfo = root.findViewById(R.id.default_tag_info);
|
||||
visibilityButton = root.findViewById(R.id.visibility_button);
|
||||
tootEditText = root.findViewById(R.id.toot_edit_text);
|
||||
openAnnouncementsButton = root.findViewById(R.id.button_open_announcements);
|
||||
announcementsText = root.findViewById(R.id.text_view_announcements);
|
||||
prevButton = root.findViewById(R.id.button_prev_announcements);
|
||||
nextButton = root.findViewById(R.id.button_next_announcements);
|
||||
announcementsCountText = root.findViewById(R.id.text_view_announcements_count);
|
||||
quickTootButton = root.findViewById(R.id.toot_button);
|
||||
|
||||
context = root.getContext();
|
||||
this.defPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
AccountEntity account = accountManager.getActiveAccount();
|
||||
if (account != null) {
|
||||
domain = account.getDomain();
|
||||
loggedInUsername = account.getUsername();
|
||||
}
|
||||
|
||||
this.eventHub = eventHub;
|
||||
|
||||
updateVisibilityButton();
|
||||
updateDefaultTagInfo();
|
||||
visibilityButton.setOnClickListener(v -> setNextVisibility());
|
||||
quickTootButton.setOnClickListener(v -> quickToot());
|
||||
|
||||
listener = new LinkListener() {
|
||||
@Override
|
||||
public void onViewTag(String tag) {
|
||||
context.startActivity(ViewTagActivity.getIntent(context, tag));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAccount(String id) {
|
||||
context.startActivity(AccountActivity.getIntent(context, id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewUrl(String url, String text) {
|
||||
activity.viewUrl(url, PostLookupFallbackBehavior.OPEN_IN_BROWSER, text);
|
||||
}
|
||||
};
|
||||
activity.mastodonApi.listAnnouncements()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.as(autoDisposable(from(activity, Lifecycle.Event.ON_DESTROY)))
|
||||
.subscribe(
|
||||
a -> {
|
||||
announcements = a;
|
||||
updateAnnouncements();
|
||||
},
|
||||
Throwable::printStackTrace
|
||||
);
|
||||
updateAnnouncements();
|
||||
openAnnouncementsButton.setOnClickListener(v -> toggleOpenAnnouncements());
|
||||
announcementsText.setOnClickListener(v -> toggleOpenAnnouncements());
|
||||
prevButton.setOnClickListener(v -> prevAnnouncement());
|
||||
nextButton.setOnClickListener(v -> nextAnnouncement());
|
||||
}
|
||||
|
||||
public void composeButton() {
|
||||
if (tootEditText.getText().length() == 0 && inReplyTo == null) {
|
||||
context.startActivity(getComposeIntent(context, true, false));
|
||||
} else {
|
||||
startComposeWithQuickComposeData();
|
||||
}
|
||||
}
|
||||
|
||||
public void handleEvent(Event event) {
|
||||
if (event instanceof QuickReplyEvent) {
|
||||
reply(((QuickReplyEvent) event).getStatus());
|
||||
} else if (event instanceof PreferenceChangedEvent) {
|
||||
switch (((PreferenceChangedEvent) event).getPreferenceKey()) {
|
||||
case PREF_CURRENT_VISIBILITY: {
|
||||
updateVisibilityButton();
|
||||
break;
|
||||
}
|
||||
case PREF_DEFAULT_TAG:
|
||||
case PREF_USE_DEFAULT_TAG: {
|
||||
updateDefaultTagInfo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (event instanceof DrawerFooterClickedEvent) {
|
||||
tootEditText.setText("にゃーん");
|
||||
}
|
||||
}
|
||||
|
||||
private void reply(Status status) {
|
||||
inReplyTo = status;
|
||||
updateQuickReplyInfo();
|
||||
}
|
||||
|
||||
private void startComposeWithQuickComposeData() {
|
||||
Intent intent = getComposeIntent(context, false, false);
|
||||
resetQuickCompose();
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
private void quickToot() {
|
||||
if (tootEditText.getText().toString().length() > 0) {
|
||||
Intent intent = getComposeIntent(context, false, true);
|
||||
resetQuickCompose();
|
||||
context.startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
private Intent getComposeIntent(Context context, boolean onlyVisibility, boolean tootRightNow) {
|
||||
ComposeActivity.ComposeOptions options = new ComposeActivity.ComposeOptions();
|
||||
options.setVisibility(getCurrentVisibility());
|
||||
if (onlyVisibility) {
|
||||
return ComposeActivity.startIntent(context, options);
|
||||
}
|
||||
options.setTootText(tootEditText.getText().toString());
|
||||
options.setTootRightNow(tootRightNow);
|
||||
|
||||
if (inReplyTo != null) {
|
||||
Status.Mention[] mentions = inReplyTo.getMentions();
|
||||
Set<String> mentionedUsernames = new LinkedHashSet<>();
|
||||
mentionedUsernames.add(inReplyTo.getAccount().getUsername());
|
||||
for (Status.Mention mention : mentions) {
|
||||
mentionedUsernames.add(mention.getUsername());
|
||||
}
|
||||
mentionedUsernames.remove(loggedInUsername);
|
||||
|
||||
options.setInReplyToId(inReplyTo.getId());
|
||||
options.setContentWarning(inReplyTo.getSpoilerText());
|
||||
options.setMentionedUsernames(mentionedUsernames);
|
||||
options.setReplyingStatusAuthor(inReplyTo.getAccount().getLocalUsername());
|
||||
options.setReplyingStatusContent(inReplyTo.getContent().toString());
|
||||
}
|
||||
|
||||
return ComposeActivity.startIntent(context, options);
|
||||
}
|
||||
|
||||
private void resetQuickCompose() {
|
||||
tootEditText.getText().clear();
|
||||
inReplyTo = null;
|
||||
updateQuickReplyInfo();
|
||||
}
|
||||
|
||||
private void updateQuickReplyInfo() {
|
||||
if (inReplyTo != null) {
|
||||
quickReplyInfo.setText(String.format("Reply to : %s", inReplyTo.getAccount().getUsername()));
|
||||
} else {
|
||||
quickReplyInfo.setText("");
|
||||
}
|
||||
}
|
||||
|
||||
private void updateDefaultTagInfo() {
|
||||
boolean useDefaultTag = defPrefs.getBoolean(PREF_USE_DEFAULT_TAG, false);
|
||||
String defaultText = defPrefs.getString(PREF_DEFAULT_TAG, "");
|
||||
if (useDefaultTag) {
|
||||
defaultTagInfo.setText(String.format("%s : %s", context.getString(R.string.hint_default_text), defaultText));
|
||||
defaultTagInfo.setTextColor(ThemeUtils.getColor(context, R.attr.colorInfo));
|
||||
} else {
|
||||
defaultTagInfo.setText(String.format("%s inactive", context.getString(R.string.hint_default_text)));
|
||||
defaultTagInfo.setTextColor(ThemeUtils.getColor(context, android.R.attr.textColorTertiary));
|
||||
}
|
||||
}
|
||||
|
||||
private Status.Visibility getCurrentVisibility() {
|
||||
Status.Visibility visibility = Status.Visibility.byNum(defPrefs.getInt(PREF_CURRENT_VISIBILITY, Status.Visibility.PUBLIC.getNum()));
|
||||
if (!Arrays.asList(CAN_USE_UNLEAKABLE)
|
||||
.contains(domain) && visibility == Status.Visibility.UNLEAKABLE) {
|
||||
defPrefs.edit()
|
||||
.putInt(PREF_CURRENT_VISIBILITY, Status.Visibility.PUBLIC.getNum())
|
||||
.apply();
|
||||
eventHub.dispatch(new PreferenceChangedEvent(PREF_CURRENT_VISIBILITY));
|
||||
return Status.Visibility.PUBLIC;
|
||||
}
|
||||
return visibility;
|
||||
}
|
||||
|
||||
private void updateVisibilityButton() {
|
||||
Status.Visibility visibility = getCurrentVisibility();
|
||||
quickTootButton.setStatusVisibility(visibility);
|
||||
switch (visibility) {
|
||||
case PUBLIC:
|
||||
visibilityButton.setImageResource(R.drawable.ic_public_24dp);
|
||||
break;
|
||||
case UNLISTED:
|
||||
visibilityButton.setImageResource(R.drawable.ic_lock_open_24dp);
|
||||
break;
|
||||
case PRIVATE:
|
||||
visibilityButton.setImageResource(R.drawable.ic_lock_outline_24dp);
|
||||
break;
|
||||
case UNLEAKABLE:
|
||||
visibilityButton.setImageResource(R.drawable.ic_low_vision_24dp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setNextVisibility() {
|
||||
Status.Visibility visibility = getCurrentVisibility();
|
||||
switch (visibility) {
|
||||
case PUBLIC:
|
||||
visibility = Status.Visibility.UNLISTED;
|
||||
break;
|
||||
case UNLISTED:
|
||||
visibility = Status.Visibility.PRIVATE;
|
||||
break;
|
||||
case PRIVATE:
|
||||
if (Arrays.asList(CAN_USE_UNLEAKABLE).contains(domain)) {
|
||||
visibility = Status.Visibility.UNLEAKABLE;
|
||||
} else {
|
||||
visibility = Status.Visibility.PUBLIC;
|
||||
}
|
||||
break;
|
||||
case UNLEAKABLE:
|
||||
case UNKNOWN:
|
||||
visibility = Status.Visibility.PUBLIC;
|
||||
break;
|
||||
}
|
||||
defPrefs.edit()
|
||||
.putInt(PREF_CURRENT_VISIBILITY, visibility.getNum())
|
||||
.apply();
|
||||
eventHub.dispatch(new PreferenceChangedEvent(PREF_CURRENT_VISIBILITY));
|
||||
updateVisibilityButton();
|
||||
}
|
||||
|
||||
private void updateAnnouncements() {
|
||||
if (ListUtils.isEmpty(announcements)) {
|
||||
openAnnouncementsButton.setVisibility(View.GONE);
|
||||
announcementsText.setVisibility(View.GONE);
|
||||
announcementsCountText.setVisibility(View.GONE);
|
||||
prevButton.setVisibility(View.GONE);
|
||||
nextButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
openAnnouncementsButton.setVisibility(View.VISIBLE);
|
||||
announcementsText.setVisibility(View.VISIBLE);
|
||||
announcementsCountText.setVisibility(View.VISIBLE);
|
||||
if (open) {
|
||||
prevButton.setVisibility(View.VISIBLE);
|
||||
nextButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
prevButton.setVisibility(View.GONE);
|
||||
nextButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
openAnnouncementsButton.setImageDrawable(ContextCompat.getDrawable(context, open ? R.drawable.ic_arrow_drop_down : R.drawable.ic_arrow_drop_up));
|
||||
announcementsText.setSingleLine(!open);
|
||||
announcementsCountText.setText(String.format(Locale.getDefault(), "(%d/%d)", index + 1, announcements.size()));
|
||||
Announcement announcement = announcements.get(index);
|
||||
LinkHelper.setClickableText(announcementsText, announcement.getContent(), announcement.getMentions(), listener, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleOpenAnnouncements() {
|
||||
open = !open;
|
||||
updateAnnouncements();
|
||||
}
|
||||
|
||||
private void prevAnnouncement() {
|
||||
if (index > 0) {
|
||||
index--;
|
||||
updateAnnouncements();
|
||||
}
|
||||
}
|
||||
|
||||
private void nextAnnouncement() {
|
||||
if (index < announcements.size() - 1) {
|
||||
index++;
|
||||
updateAnnouncements();
|
||||
}
|
||||
}
|
||||
}
|
98
app/src/main/java/net/accelf/yuito/QuickTootView.kt
Normal file
98
app/src/main/java/net/accelf/yuito/QuickTootView.kt
Normal file
@ -0,0 +1,98 @@
|
||||
package net.accelf.yuito
|
||||
|
||||
import android.content.Context
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.appstore.Event
|
||||
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent
|
||||
import com.keylesspalace.tusky.appstore.QuickReplyEvent
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity.Companion.PREF_DEFAULT_TAG
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity.Companion.PREF_USE_DEFAULT_TAG
|
||||
import com.keylesspalace.tusky.util.ThemeUtils
|
||||
import kotlinx.android.synthetic.main.view_quick_toot.view.*
|
||||
|
||||
class QuickTootView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
ConstraintLayout(context, attrs) {
|
||||
|
||||
private val preference by lazy { PreferenceManager.getDefaultSharedPreferences(context) }
|
||||
|
||||
private lateinit var viewModel: QuickTootViewModel
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_quick_toot, this, true)
|
||||
}
|
||||
|
||||
fun attachViewModel(viewModel: QuickTootViewModel, owner: LifecycleOwner) {
|
||||
this.viewModel = viewModel
|
||||
|
||||
buttonVisibility.attachViewModel(viewModel, owner)
|
||||
|
||||
viewModel.content.observe(owner) {
|
||||
if (editTextContent.text.toString() != it) {
|
||||
editTextContent.setText(it)
|
||||
}
|
||||
}
|
||||
editTextContent.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
viewModel.content.value = s.toString()
|
||||
}
|
||||
})
|
||||
|
||||
viewModel.inReplyTo.observe(owner) {
|
||||
textQuickReply.text = it?.let { "Reply to ${it.account.username}" } ?: ""
|
||||
}
|
||||
|
||||
viewModel.defaultTag.observe(owner) {
|
||||
textDefaultTag.text = it?.let { "${context.getString(R.string.hint_default_text)} : $it" }
|
||||
?: "${context.getString(R.string.hint_default_text)} inactive"
|
||||
textDefaultTag.setTextColor(ThemeUtils.getColor(context, it?.let { R.attr.colorInfo }
|
||||
?: android.R.attr.textColorTertiary))
|
||||
}
|
||||
syncDefaultTag()
|
||||
|
||||
viewModel.visibility.observe(owner) {
|
||||
buttonToot.setStatusVisibility(it)
|
||||
}
|
||||
buttonToot.setOnClickListener {
|
||||
val intent = ComposeActivity.startIntent(it.context, viewModel.composeOptions(true))
|
||||
viewModel.reset()
|
||||
it.context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun syncDefaultTag() {
|
||||
viewModel.defaultTag.value = if (preference.getBoolean(PREF_USE_DEFAULT_TAG, false)) {
|
||||
preference.getString(PREF_DEFAULT_TAG, null)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun onFABClicked(view: View) {
|
||||
val intent = ComposeActivity.startIntent(view.context, viewModel.composeOptions(false))
|
||||
viewModel.reset()
|
||||
view.context.startActivity(intent)
|
||||
}
|
||||
|
||||
fun handleEvent(event: Event?) {
|
||||
when (event) {
|
||||
is QuickReplyEvent -> viewModel.reply(event)
|
||||
is PreferenceChangedEvent -> {
|
||||
if (event.preferenceKey in arrayOf(PREF_DEFAULT_TAG, PREF_USE_DEFAULT_TAG)) {
|
||||
syncDefaultTag()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
91
app/src/main/java/net/accelf/yuito/QuickTootViewModel.kt
Normal file
91
app/src/main/java/net/accelf/yuito/QuickTootViewModel.kt
Normal file
@ -0,0 +1,91 @@
|
||||
package net.accelf.yuito
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.keylesspalace.tusky.appstore.QuickReplyEvent
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity
|
||||
import com.keylesspalace.tusky.components.compose.ComposeActivity.Companion.CAN_USE_UNLEAKABLE
|
||||
import com.keylesspalace.tusky.components.compose.mutableLiveData
|
||||
import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.entity.Status.Visibility
|
||||
import javax.inject.Inject
|
||||
|
||||
class QuickTootViewModel @Inject constructor(
|
||||
accountManager: AccountManager
|
||||
): ViewModel() {
|
||||
|
||||
private val account = accountManager.activeAccount!!
|
||||
|
||||
private val unleakableAllowed by lazy { CAN_USE_UNLEAKABLE.contains(account.domain) }
|
||||
|
||||
val content = mutableLiveData("")
|
||||
|
||||
private val visibilityMutable = mutableLiveData(Visibility.PUBLIC)
|
||||
val visibility: LiveData<Visibility> = visibilityMutable
|
||||
private var stashedVisibility: Visibility? = null
|
||||
|
||||
private val inReplyToMutable: MutableLiveData<Status?> = mutableLiveData(null)
|
||||
val inReplyTo: LiveData<Status?> = inReplyToMutable
|
||||
|
||||
val defaultTag: MutableLiveData<String?> = mutableLiveData(null)
|
||||
|
||||
fun setInitialVisibility(num: Int) {
|
||||
visibilityMutable.value = (Visibility.byNum(num)
|
||||
.takeUnless { it == Visibility.UNKNOWN }
|
||||
?: account.defaultPostPrivacy)
|
||||
.takeUnless { it == Visibility.UNLEAKABLE && unleakableAllowed }
|
||||
?: Visibility.PRIVATE
|
||||
}
|
||||
|
||||
fun stepVisibility() {
|
||||
visibilityMutable.value = when (visibility.value) {
|
||||
Visibility.PUBLIC -> Visibility.UNLISTED
|
||||
Visibility.UNLISTED -> Visibility.PRIVATE
|
||||
Visibility.PRIVATE -> when (unleakableAllowed) {
|
||||
true -> Visibility.UNLEAKABLE
|
||||
false -> Visibility.PUBLIC
|
||||
}
|
||||
Visibility.UNLEAKABLE -> Visibility.PUBLIC
|
||||
else -> Visibility.PUBLIC
|
||||
}
|
||||
}
|
||||
|
||||
private fun overrideVisibility(overrideTo: Visibility) {
|
||||
stashedVisibility = visibility.value
|
||||
visibilityMutable.value = overrideTo
|
||||
}
|
||||
|
||||
fun reply(event: QuickReplyEvent) {
|
||||
val status = event.status.actionableStatus
|
||||
inReplyToMutable.value = status
|
||||
overrideVisibility(status.visibility)
|
||||
}
|
||||
|
||||
fun composeOptions(tootRightNow: Boolean): ComposeActivity.ComposeOptions {
|
||||
return ComposeActivity.ComposeOptions(
|
||||
tootText = content.value,
|
||||
mentionedUsernames = inReplyTo.value
|
||||
?.let {
|
||||
linkedSetOf(it.account.username, *(it.mentions.map { mention -> mention.username }.toTypedArray()))
|
||||
.apply { remove(account.username) }
|
||||
},
|
||||
inReplyToId = inReplyTo.value?.id,
|
||||
visibility = visibility.value,
|
||||
contentWarning = inReplyTo.value?.spoilerText,
|
||||
replyingStatusAuthor = inReplyTo.value?.account?.name,
|
||||
replyingStatusContent = inReplyTo.value?.content?.toString(),
|
||||
tootRightNow = tootRightNow
|
||||
)
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
content.value = ""
|
||||
inReplyToMutable.value = null
|
||||
stashedVisibility?.let {
|
||||
visibilityMutable.value = stashedVisibility
|
||||
stashedVisibility = null
|
||||
}
|
||||
}
|
||||
}
|
59
app/src/main/java/net/accelf/yuito/VisibilityToggleButton.kt
Normal file
59
app/src/main/java/net/accelf/yuito/VisibilityToggleButton.kt
Normal file
@ -0,0 +1,59 @@
|
||||
package net.accelf.yuito
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.observe
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.entity.Status.Visibility
|
||||
|
||||
class VisibilityToggleButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
AppCompatImageView(context, attrs) {
|
||||
|
||||
private val preference by lazy { PreferenceManager.getDefaultSharedPreferences(context) }
|
||||
|
||||
init {
|
||||
isClickable = true
|
||||
isFocusable = true
|
||||
}
|
||||
|
||||
fun attachViewModel(viewModel: QuickTootViewModel, owner: LifecycleOwner) {
|
||||
viewModel.visibility.observe(owner, ::updateVisibility)
|
||||
viewModel.setInitialVisibility(preference.getInt(PREF_CURRENT_VISIBILITY, Visibility.UNKNOWN.num))
|
||||
setOnClickListener{ viewModel.stepVisibility() }
|
||||
}
|
||||
|
||||
private fun updateVisibility(visibility: Visibility) {
|
||||
setImageResource(
|
||||
when (visibility) {
|
||||
Visibility.PUBLIC -> R.drawable.ic_public_24dp
|
||||
Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp
|
||||
Visibility.PRIVATE -> R.drawable.ic_lock_outline_24dp
|
||||
Visibility.DIRECT -> R.drawable.ic_email_24dp
|
||||
Visibility.UNLEAKABLE -> R.drawable.ic_low_vision_24dp
|
||||
else -> R.drawable.ic_lock_open_24dp
|
||||
}
|
||||
)
|
||||
|
||||
contentDescription = context.getString(
|
||||
when (visibility) {
|
||||
Visibility.UNKNOWN -> R.string.visibility_unknown
|
||||
Visibility.PUBLIC -> R.string.visibility_public
|
||||
Visibility.UNLISTED -> R.string.visibility_unlisted
|
||||
Visibility.PRIVATE -> R.string.visibility_private
|
||||
Visibility.DIRECT -> R.string.visibility_direct
|
||||
Visibility.UNLEAKABLE -> R.string.visibility_unleakable
|
||||
}
|
||||
)
|
||||
|
||||
preference.edit()
|
||||
.putInt(PREF_CURRENT_VISIBILITY, visibility.num)
|
||||
.apply()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREF_CURRENT_VISIBILITY = "current_visibility"
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7,10l5,5 5,-5z"/>
|
||||
</vector>
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M7,14l5,-5 5,5z"/>
|
||||
</vector>
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z"/>
|
||||
</vector>
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M10,6L8.59,7.41 13.17,12l-4.58,4.59L10,18l6,-6z"/>
|
||||
</vector>
|
@ -81,9 +81,8 @@
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/quickTootContainer"
|
||||
layout="@layout/view_quick_toot"
|
||||
<net.accelf.yuito.QuickTootView
|
||||
android:id="@+id/viewQuickToot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0" />
|
||||
|
@ -35,11 +35,10 @@
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/quick_toot_container"
|
||||
layout="@layout/view_quick_toot"
|
||||
<net.accelf.yuito.QuickTootView
|
||||
android:id="@+id/viewQuickToot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -35,11 +35,10 @@
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/quick_toot_container"
|
||||
layout="@layout/view_quick_toot"
|
||||
<net.accelf.yuito.QuickTootView
|
||||
android:id="@+id/viewQuickToot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -25,11 +25,10 @@
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/quick_toot_container"
|
||||
layout="@layout/view_quick_toot"
|
||||
<net.accelf.yuito.QuickTootView
|
||||
android:id="@+id/viewQuickToot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
@ -5,101 +5,32 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/colorSurface">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_open_announcements"
|
||||
style="@style/TuskyImageButton"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:padding="4dp"
|
||||
android:contentDescription="@string/action_more"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toTopOf="@+id/quick_reply_info"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:srcCompat="@drawable/ic_arrow_drop_up" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_announcements"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/quick_reply_info"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/button_open_announcements" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_prev_announcements"
|
||||
style="@style/TuskyImageButton"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:padding="4dp"
|
||||
android:contentDescription="@string/action_more"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toTopOf="@+id/text_view_announcements_count"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_next_announcements"
|
||||
app:srcCompat="@drawable/ic_chevron_left" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/button_next_announcements"
|
||||
style="@style/TuskyImageButton"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:padding="4dp"
|
||||
android:contentDescription="@string/action_more"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toTopOf="@+id/text_view_announcements_count"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:srcCompat="@drawable/ic_chevron_right" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_view_announcements_count"
|
||||
android:id="@+id/textQuickReply"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="4dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/quick_reply_info"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/quick_reply_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@id/toot_edit_text"
|
||||
app:layout_constraintBottom_toTopOf="@id/editTextContent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/default_tag_info"
|
||||
android:id="@+id/textDefaultTag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@id/toot_edit_text"
|
||||
app:layout_constraintBottom_toTopOf="@id/editTextContent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/visibility_button"
|
||||
<net.accelf.yuito.VisibilityToggleButton
|
||||
android:id="@+id/buttonVisibility"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@null"
|
||||
android:focusable="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:srcCompat="@drawable/ic_public_24dp" />
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/toot_edit_text"
|
||||
android:id="@+id/editTextContent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints=""
|
||||
@ -107,11 +38,11 @@
|
||||
android:inputType="textMultiLine"
|
||||
android:minHeight="48dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/toot_button"
|
||||
app:layout_constraintStart_toEndOf="@id/visibility_button" />
|
||||
app:layout_constraintEnd_toStartOf="@id/buttonToot"
|
||||
app:layout_constraintStart_toEndOf="@id/buttonVisibility" />
|
||||
|
||||
<com.keylesspalace.tusky.components.compose.view.TootButton
|
||||
android:id="@+id/toot_button"
|
||||
android:id="@+id/buttonToot"
|
||||
style="@style/TuskyButton"
|
||||
android:layout_width="@dimen/toot_button_width"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -224,6 +224,7 @@
|
||||
<string name="visibility_private">Followers-Only: Post to followers only</string>
|
||||
<string name="visibility_unleakable">Unleakable: Post to followed user by you only.</string>
|
||||
<string name="visibility_direct">Direct: Post to mentioned users only</string>
|
||||
<string name="visibility_unknown">Unknown visibility</string>
|
||||
|
||||
<string name="pref_title_edit_notification_settings">Notifications</string>
|
||||
<string name="pref_title_notifications_enabled">Notifications</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user