[default-tag] Implement default-tag feature

This commit is contained in:
kyori 2018-09-04 18:34:42 +09:00 committed by kyori19
parent ad7ff6d06b
commit 75c4cdd886
11 changed files with 121 additions and 21 deletions

View File

@ -55,6 +55,7 @@ import android.view.Window;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
@ -90,6 +91,8 @@ import com.google.gson.reflect.TypeToken;
import com.keylesspalace.tusky.adapter.ComposeAutoCompleteAdapter;
import com.keylesspalace.tusky.adapter.EmojiAdapter;
import com.keylesspalace.tusky.adapter.OnEmojiSelectedListener;
import com.keylesspalace.tusky.appstore.EventHub;
import com.keylesspalace.tusky.appstore.PreferenceChangedEvent;
import com.keylesspalace.tusky.db.AccountEntity;
import com.keylesspalace.tusky.db.AppDatabase;
import com.keylesspalace.tusky.db.InstanceEntity;
@ -206,10 +209,15 @@ public final class ComposeActivity
public static final String[] CAN_USE_UNLEAKABLE = {"itabashi.0j0.jp", "odakyu.app"};
private static final String[] CAN_USE_QUOTE_ID = {"odakyu.app", "biwakodon.com", "dtp-mstdn.jp", "nitiasa.com"};
public static final String PREF_DEFAULT_TAG = "default_tag";
public static final String PREF_USE_DEFAULT_TAG = "use_default_tag";
@Inject
public MastodonApi mastodonApi;
@Inject
public AppDatabase database;
@Inject
public EventHub eventHub;
private TextView replyTextView;
private TextView replyContentTextView;
@ -217,6 +225,8 @@ public final class ComposeActivity
private LinearLayout mediaPreviewBar;
private View contentWarningBar;
private EditText contentWarningEditor;
private CheckBox useDefaultTag;
private EditText defaultTagEditText;
private TextView charactersLeft;
private TootButton tootButton;
private ImageButton pickButton;
@ -265,10 +275,12 @@ public final class ComposeActivity
private SaveTootHelper saveTootHelper;
private Gson gson = new Gson();
private SharedPreferences preferences;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
String theme = preferences.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT);
if (theme.equals("black")) {
setTheme(R.style.TuskyDialogActivityBlackTheme);
@ -282,6 +294,8 @@ public final class ComposeActivity
mediaPreviewBar = findViewById(R.id.compose_media_preview_bar);
contentWarningBar = findViewById(R.id.composeContentWarningBar);
contentWarningEditor = findViewById(R.id.composeContentWarningField);
useDefaultTag = findViewById(R.id.checkbox_use_default_text);
defaultTagEditText = findViewById(R.id.edittext_default_text);
charactersLeft = findViewById(R.id.composeCharactersLeftView);
tootButton = findViewById(R.id.composeTootButton);
pickButton = findViewById(R.id.composeAddMediaButton);
@ -381,6 +395,10 @@ public final class ComposeActivity
enableButton(emojiButton, false, false);
restoreDefaultTagStatus();
useDefaultTag.setOnCheckedChangeListener((compoundButton, b) -> saveDefaultTagStatus());
defaultTagEditText.setOnFocusChangeListener((view, b) -> saveDefaultTagStatus());
// Setup the interface buttons.
tootButton.setOnClickListener(v -> onSendClicked());
pickButton.setOnClickListener(v -> openPickDialog());
@ -923,6 +941,20 @@ public final class ComposeActivity
}
private void restoreDefaultTagStatus() {
useDefaultTag.setChecked(preferences.getBoolean(PREF_USE_DEFAULT_TAG, false));
defaultTagEditText.setText(preferences.getString(PREF_DEFAULT_TAG, ""));
}
private void saveDefaultTagStatus() {
preferences.edit()
.putString(PREF_DEFAULT_TAG, defaultTagEditText.getText().toString())
.putBoolean(PREF_USE_DEFAULT_TAG, useDefaultTag.isChecked())
.apply();
eventHub.dispatch(new PreferenceChangedEvent(PREF_DEFAULT_TAG));
eventHub.dispatch(new PreferenceChangedEvent(PREF_USE_DEFAULT_TAG));
}
private void openPickDialog() {
if (addMediaBehavior.getState() == BottomSheetBehavior.STATE_HIDDEN || addMediaBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) {
addMediaBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
@ -1193,7 +1225,9 @@ public final class ComposeActivity
private void onReadySuccess(Status.Visibility visibility, boolean sensitive) {
/* Validate the status meets the character limit. */
String contentText = textEditor.getText().toString();
saveDefaultTagStatus();
String contentText = useDefaultTag.isChecked() ?
(textEditor.getText().toString() + " " + defaultTagEditText.getText().toString()) : textEditor.getText().toString();
String spoilerText = "";
if (statusHideText) {
spoilerText = contentWarningEditor.getText().toString();
@ -1783,6 +1817,7 @@ public final class ComposeActivity
@Override
public void onBackPressed() {
saveDefaultTagStatus();
// Acting like a teen: deliberately ignoring parent.
if (composeOptionsBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED ||
addMediaBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED ||

View File

@ -16,7 +16,6 @@
package com.keylesspalace.tusky;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.MenuItem;
import androidx.annotation.Nullable;
@ -69,8 +68,7 @@ public class FavouritesActivity extends BottomSheetActivity implements HasAndroi
fragmentTransaction.commit();
ConstraintLayout quickTootContainer = findViewById(R.id.quick_toot_container);
QuickTootHelper quickTootHelper = new QuickTootHelper(quickTootContainer,
PreferenceManager.getDefaultSharedPreferences(this), accountManager, eventHub);
QuickTootHelper quickTootHelper = new QuickTootHelper(quickTootContainer, accountManager, eventHub);
eventHub.getEvents()
.observeOn(AndroidSchedulers.mainThread())

View File

@ -185,8 +185,7 @@ public final class MainActivity extends BottomSheetActivity implements ActionBut
viewPager = findViewById(R.id.pager);
ConstraintLayout quickTootContainer = findViewById(R.id.quick_toot_container);
QuickTootHelper quickTootHelper = new QuickTootHelper(quickTootContainer,
PreferenceManager.getDefaultSharedPreferences(this), accountManager, eventHub);
QuickTootHelper quickTootHelper = new QuickTootHelper(quickTootContainer, accountManager, eventHub);
composeButton.setOnClickListener(v -> quickTootHelper.composeButton());
tabLayout.requestFocus();

View File

@ -3,7 +3,6 @@ package com.keylesspalace.tusky
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.preference.PreferenceManager
import android.view.MenuItem
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.Lifecycle
@ -64,8 +63,7 @@ class ModalTimelineActivity : BottomSheetActivity(), ActionButtonActivity, HasAn
}
val quickTootContainer = findViewById<ConstraintLayout>(R.id.quick_toot_container)
val quickTootHelper = QuickTootHelper(quickTootContainer,
PreferenceManager.getDefaultSharedPreferences(this), accountManager, eventHub)
val quickTootHelper = QuickTootHelper(quickTootContainer, accountManager, eventHub)
eventHub.events
.observeOn(AndroidSchedulers.mainThread())

View File

@ -18,7 +18,6 @@ package com.keylesspalace.tusky;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.MenuItem;
import androidx.annotation.Nullable;
@ -82,8 +81,7 @@ public class ViewTagActivity extends BottomSheetActivity implements HasAndroidIn
fragmentTransaction.commit();
ConstraintLayout quickTootContainer = findViewById(R.id.quick_toot_container);
QuickTootHelper quickTootHelper = new QuickTootHelper(quickTootContainer,
PreferenceManager.getDefaultSharedPreferences(this), accountManager, eventHub);
QuickTootHelper quickTootHelper = new QuickTootHelper(quickTootContainer, accountManager, eventHub);
eventHub.getEvents()
.observeOn(AndroidSchedulers.mainThread())

View File

@ -19,6 +19,9 @@ import android.content.Context;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.provider.Settings;
import android.util.TypedValue;
import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
@ -26,8 +29,6 @@ import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDelegate;
import android.provider.Settings;
import android.util.TypedValue;
import javax.inject.Inject;
import javax.inject.Singleton;
@ -45,7 +46,7 @@ public class ThemeUtils {
public static final String APP_THEME_DEFAULT = ThemeUtils.THEME_NIGHT;
private static final String THEME_NIGHT = "night";
private static final String THEME_DAY = "day";
public static final String THEME_DAY = "day";
private static final String THEME_BLACK = "black";
private static final String THEME_AUTO = "auto";
public static final String THEME_SYSTEM = "auto_system";

View File

@ -3,6 +3,8 @@ package net.accelf.yuito;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
@ -19,15 +21,20 @@ import com.keylesspalace.tusky.appstore.QuickReplyEvent;
import com.keylesspalace.tusky.db.AccountEntity;
import com.keylesspalace.tusky.db.AccountManager;
import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.util.ThemeUtils;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import static com.keylesspalace.tusky.ComposeActivity.PREF_DEFAULT_TAG;
import static com.keylesspalace.tusky.ComposeActivity.PREF_USE_DEFAULT_TAG;
public class QuickTootHelper {
private Context context;
private TextView quickReplyInfo;
private TextView defaultTagInfo;
private ImageView visibilityButton;
private EditText tootEditText;
@ -40,14 +47,16 @@ public class QuickTootHelper {
private static final String PREF_CURRENT_VISIBILITY = "current_visibility";
public QuickTootHelper(ConstraintLayout root, SharedPreferences defPrefs, AccountManager accountManager, EventHub eventHub) {
public QuickTootHelper(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);
Button quickTootButton = root.findViewById(R.id.toot_button);
this.defPrefs = defPrefs;
context = root.getContext();
this.defPrefs = PreferenceManager.getDefaultSharedPreferences(context);
AccountEntity account = accountManager.getActiveAccount();
if (account != null) {
domain = account.getDomain();
@ -57,6 +66,7 @@ public class QuickTootHelper {
this.eventHub = eventHub;
updateVisibilityButton();
updateDefaultTagInfo();
visibilityButton.setOnClickListener(v -> setNextVisibility());
quickTootButton.setOnClickListener(v -> quickToot());
}
@ -74,8 +84,16 @@ public class QuickTootHelper {
if (event instanceof QuickReplyEvent) {
reply(((QuickReplyEvent) event).getStatus());
} else if (event instanceof PreferenceChangedEvent) {
if (PREF_CURRENT_VISIBILITY.equals(((PreferenceChangedEvent) event).getPreferenceKey())) {
updateVisibilityButton();
switch (((PreferenceChangedEvent) event).getPreferenceKey()) {
case PREF_CURRENT_VISIBILITY: {
updateVisibilityButton();
break;
}
case PREF_DEFAULT_TAG:
case PREF_USE_DEFAULT_TAG: {
updateDefaultTagInfo();
break;
}
}
}
}
@ -139,6 +157,22 @@ public class QuickTootHelper {
}
}
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));
if (ThemeUtils.THEME_DAY.equals(defPrefs.getString("appTheme", ThemeUtils.APP_THEME_DEFAULT))) {
defaultTagInfo.setTextColor(Color.RED);
} else {
defaultTagInfo.setTextColor(Color.YELLOW);
}
} else {
defaultTagInfo.setText(String.format("%s inactive", context.getString(R.string.hint_default_text)));
defaultTagInfo.setTextColor(Color.GRAY);
}
}
private Status.Visibility getCurrentVisibility() {
Status.Visibility visibility = Status.Visibility.byNum(defPrefs.getInt(PREF_CURRENT_VISIBILITY, Status.Visibility.PUBLIC.getNum()));
if (!Arrays.asList(ComposeActivity.CAN_USE_UNLEAKABLE)

View File

@ -53,7 +53,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/compose_activity_scrollview_height"
android:layout_marginTop="?attr/actionBarSize"
android:layout_marginBottom="52dp">
android:layout_marginBottom="116dp">
<LinearLayout
android:layout_width="match_parent"
@ -170,6 +170,34 @@
</LinearLayout>
</androidx.core.widget.NestedScrollView>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingBottom="52dp" >
<CheckBox
android:id="@+id/checkbox_use_default_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<EditText
android:id="@+id/edittext_default_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/hint_default_text"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/checkbox_use_default_text"
tools:ignore="Autofill" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:id="@+id/addMediaBottomSheet"
android:layout_width="match_parent"

View File

@ -12,6 +12,13 @@
app:layout_constraintBottom_toTopOf="@id/toot_edit_text"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/default_tag_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/toot_edit_text"
app:layout_constraintEnd_toEndOf="parent" />
<ImageView
android:id="@+id/visibility_button"
android:layout_width="24dp"

View File

@ -128,6 +128,7 @@
<string name="hint_display_name">表示名</string>
<string name="hint_note">プロフィール</string>
<string name="hint_search">ユーザーを検索…</string>
<string name="hint_default_text">実況モード</string>
<string name="search_no_results">見つかりませんでした</string>
<string name="label_quick_reply">返信…</string>
<string name="label_avatar">アイコン</string>

View File

@ -159,6 +159,7 @@
<string name="hint_note">Bio</string>
<string name="hint_search">Search…</string>
<string name="hint_toot_area">Quick Toot Area</string>
<string name="hint_default_text">Default Hashtag</string>
<string name="search_no_results">No results</string>