parent
e45f3f30f3
commit
ed9813f093
|
@ -0,0 +1,19 @@
|
|||
package org.joinmastodon.android.api.requests.lists;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
|
||||
public class CreateList extends MastodonAPIRequest<ListTimeline> {
|
||||
public CreateList(String title, ListTimeline.RepliesPolicy repliesPolicy) {
|
||||
super(HttpMethod.POST, "/lists", ListTimeline.class);
|
||||
Request req = new Request();
|
||||
req.title = title;
|
||||
req.repliesPolicy = repliesPolicy;
|
||||
setRequestBody(req);
|
||||
}
|
||||
|
||||
public static class Request {
|
||||
public String title;
|
||||
public ListTimeline.RepliesPolicy repliesPolicy;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.joinmastodon.android.api.requests.lists;
|
||||
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
|
||||
public class UpdateList extends MastodonAPIRequest<ListTimeline> {
|
||||
public UpdateList(String id, String title, ListTimeline.RepliesPolicy repliesPolicy) {
|
||||
super(HttpMethod.PUT, "/lists/" + id, ListTimeline.class);
|
||||
CreateList.Request req = new CreateList.Request();
|
||||
req.title = title;
|
||||
req.repliesPolicy = repliesPolicy;
|
||||
setRequestBody(req);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package org.joinmastodon.android.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
|
@ -12,16 +15,21 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||
import org.joinmastodon.android.api.requests.lists.AddAccountsToList;
|
||||
import org.joinmastodon.android.api.requests.lists.CreateList;
|
||||
import org.joinmastodon.android.api.requests.lists.GetLists;
|
||||
import org.joinmastodon.android.api.requests.lists.RemoveAccountsFromList;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.ListTimelineEditor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
import me.grishka.appkit.api.SimpleCallback;
|
||||
import me.grishka.appkit.fragments.BaseRecyclerFragment;
|
||||
import me.grishka.appkit.utils.BindableViewHolder;
|
||||
|
@ -34,6 +42,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||
private HashMap<String, Boolean> userInListBefore = new HashMap<>();
|
||||
private HashMap<String, Boolean> userInList = new HashMap<>();
|
||||
private int inProgress = 0;
|
||||
private ListsAdapter adapter;
|
||||
|
||||
public ListTimelinesFragment() {
|
||||
super(10);
|
||||
|
@ -49,7 +58,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||
profileAccountId=args.getString("profileAccount");
|
||||
profileDisplayUsername=args.getString("profileDisplayUsername");
|
||||
setTitle(getString(R.string.sk_lists_with_user, profileDisplayUsername));
|
||||
// setHasOptionsMenu(true);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,20 +69,38 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||
loadData();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
// Button saveButton=new Button(getActivity());
|
||||
// saveButton.setText(R.string.save);
|
||||
// saveButton.setOnClickListener(this::onSaveClick);
|
||||
// LinearLayout wrap=new LinearLayout(getActivity());
|
||||
// wrap.setOrientation(LinearLayout.HORIZONTAL);
|
||||
// wrap.addView(saveButton, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
// wrap.setPadding(V.dp(16), V.dp(4), V.dp(16), V.dp(8));
|
||||
// wrap.setClipToPadding(false);
|
||||
// MenuItem item=menu.add(R.string.save);
|
||||
// item.setActionView(wrap);
|
||||
// item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
// }
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.menu_list, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == R.id.create) {
|
||||
ListTimelineEditor editor = new ListTimelineEditor(getContext());
|
||||
new M3AlertDialogBuilder(getActivity())
|
||||
.setTitle(R.string.sk_create_list_title)
|
||||
.setView(editor)
|
||||
.setPositiveButton(R.string.sk_create, (d, which) -> {
|
||||
new CreateList(editor.getTitle(), editor.getRepliesPolicy()).setCallback(new Callback<>() {
|
||||
@Override
|
||||
public void onSuccess(ListTimeline list) {
|
||||
saveListMembership(list.id, true);
|
||||
data.add(0, list);
|
||||
adapter.notifyItemRangeInserted(0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error) {
|
||||
error.showToast(getContext());
|
||||
}
|
||||
}).exec(accountId);
|
||||
})
|
||||
.setNegativeButton(R.string.cancel, (d, which) -> {})
|
||||
.show();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void saveListMembership(String listId, boolean isMember) {
|
||||
userInList.put(listId, isMember);
|
||||
|
@ -119,7 +146,7 @@ public class ListTimelinesFragment extends BaseRecyclerFragment<ListTimeline> im
|
|||
|
||||
@Override
|
||||
protected RecyclerView.Adapter getAdapter() {
|
||||
return new ListsAdapter();
|
||||
return adapter = new ListsAdapter();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -53,6 +53,7 @@ import org.joinmastodon.android.model.PushSubscription;
|
|||
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||
import org.joinmastodon.android.ui.OutlineProviders;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
import org.joinmastodon.android.ui.views.TextInputFrameLayout;
|
||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||
import org.parceler.Parcels;
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupMenu;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.ListTimeline;
|
||||
|
||||
public class ListTimelineEditor extends LinearLayout {
|
||||
private ListTimeline.RepliesPolicy policy = null;
|
||||
private TextInputFrameLayout input;
|
||||
private Button button;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public ListTimelineEditor(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
LayoutInflater.from(context).inflate(R.layout.list_timeline_editor, this);
|
||||
|
||||
button = findViewById(R.id.button);
|
||||
input = findViewById(R.id.input);
|
||||
|
||||
PopupMenu popupMenu = new PopupMenu(context, button, Gravity.CENTER_HORIZONTAL);
|
||||
popupMenu.inflate(R.menu.list_reply_policies);
|
||||
popupMenu.setOnMenuItemClickListener(this::onMenuItemClick);
|
||||
|
||||
button.setOnTouchListener(popupMenu.getDragToOpenListener());
|
||||
button.setOnClickListener(v->popupMenu.show());
|
||||
input.getEditText().setHint(context.getString(R.string.sk_list_name_hint));
|
||||
|
||||
setRepliesPolicy(ListTimeline.RepliesPolicy.LIST);
|
||||
}
|
||||
|
||||
public void applyList(ListTimeline list) {
|
||||
policy = list.repliesPolicy;
|
||||
input.getEditText().setText(list.title);
|
||||
setRepliesPolicy(list.repliesPolicy);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return input.getEditText().getText().toString();
|
||||
}
|
||||
|
||||
public ListTimeline.RepliesPolicy getRepliesPolicy() {
|
||||
return policy;
|
||||
}
|
||||
|
||||
public void setRepliesPolicy(ListTimeline.RepliesPolicy policy) {
|
||||
this.policy = policy;
|
||||
switch (policy) {
|
||||
case FOLLOWED -> button.setText(R.string.sk_list_replies_policy_followed);
|
||||
case LIST -> button.setText(R.string.sk_list_replies_policy_list);
|
||||
case NONE -> button.setText(R.string.sk_list_replies_policy_none);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean onMenuItemClick(MenuItem i) {
|
||||
if (i.getItemId() == R.id.reply_policy_none) {
|
||||
setRepliesPolicy(ListTimeline.RepliesPolicy.NONE);
|
||||
} else if (i.getItemId() == R.id.reply_policy_followed) {
|
||||
setRepliesPolicy(ListTimeline.RepliesPolicy.FOLLOWED);
|
||||
} else if (i.getItemId() == R.id.reply_policy_list) {
|
||||
setRepliesPolicy(ListTimeline.RepliesPolicy.LIST);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public ListTimelineEditor(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public ListTimelineEditor(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ListTimelineEditor(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package org.joinmastodon.android.ui.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import me.grishka.appkit.utils.V;
|
||||
|
||||
public class TextInputFrameLayout extends FrameLayout {
|
||||
private final EditText editText;
|
||||
|
||||
public TextInputFrameLayout(@NonNull Context context, CharSequence hint, CharSequence text) {
|
||||
this(context, null, 0, 0, hint, text);
|
||||
}
|
||||
|
||||
public TextInputFrameLayout(@NonNull Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public TextInputFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public TextInputFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public TextInputFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
this(context, attrs, defStyleAttr, defStyleRes, null, null);
|
||||
}
|
||||
|
||||
public TextInputFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes, CharSequence hint, CharSequence text) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
editText = new EditText(context);
|
||||
editText.setHint(hint);
|
||||
editText.setText(text);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
params.setMargins(V.dp(24), V.dp(4), V.dp(24), V.dp(16));
|
||||
editText.setLayoutParams(params);
|
||||
addView(editText);
|
||||
}
|
||||
|
||||
public EditText getEditText() {
|
||||
return editText;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||
<path android:pathData="M17.75 3c1.733 0 3.15 1.356 3.245 3.066L21 6.25v5.772c-0.463-0.297-0.966-0.536-1.5-0.709V6.25c0-0.918-0.707-1.671-1.606-1.744L17.75 4.5H6.25c-0.6 0-1.13 0.302-1.445 0.763C4.491 5.095 4.132 5 3.75 5 3.57 5 3.393 5.021 3.224 5.062 3.677 3.909 4.77 3.078 6.066 3.005L6.25 3h11.5zm-6.437 16.5c0.173 0.534 0.412 1.037 0.709 1.5H6.25c-1.733 0-3.15-1.357-3.245-3.066L3 17.75V9.372C3.235 9.455 3.487 9.5 3.75 9.5S4.266 9.455 4.5 9.372v8.378c0 0.918 0.707 1.671 1.607 1.744L6.25 19.5h5.063zm0.418-4.997c0.286-0.55 0.65-1.056 1.076-1.5h-4.06l-0.1 0.007c-0.367 0.05-0.65 0.363-0.65 0.743 0 0.414 0.337 0.75 0.75 0.75h2.984zm3.521-5.007c0.415 0 0.75 0.336 0.75 0.75 0 0.38-0.282 0.694-0.648 0.743l-0.102 0.007H8.748c-0.414 0-0.75-0.336-0.75-0.75 0-0.38 0.282-0.693 0.648-0.743l0.102-0.007h6.504zM3.75 6C4.44 6 5 6.56 5 7.25S4.44 8.5 3.75 8.5 2.5 7.94 2.5 7.25 3.06 6 3.75 6zM23 17.5c0-3.038-2.462-5.5-5.5-5.5S12 14.462 12 17.5s2.462 5.5 5.5 5.5 5.5-2.462 5.5-5.5zM18 18l0.001 2.503c0 0.277-0.224 0.5-0.5 0.5s-0.5-0.223-0.5-0.5V18h-2.505c-0.276 0-0.5-0.224-0.5-0.5s0.224-0.5 0.5-0.5H17v-2.5c0-0.277 0.224-0.5 0.5-0.5s0.5 0.223 0.5 0.5V17h2.497c0.276 0 0.5 0.224 0.5 0.5s-0.224 0.5-0.5 0.5H18z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||
</vector>
|
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<org.joinmastodon.android.ui.views.AutoOrientationLinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginHorizontal="24dp">
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:text="@string/sk_list_replies_policy"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingVertical="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:layout_weight="0"
|
||||
android:maxWidth="140dp"
|
||||
android:background="@drawable/bg_inline_button"
|
||||
android:elevation="0dp"
|
||||
android:ellipsize="middle"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:singleLine="true"
|
||||
android:stateListAnimator="@null"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="16sp" />
|
||||
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
||||
|
||||
<org.joinmastodon.android.ui.views.TextInputFrameLayout
|
||||
android:id="@+id/input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/reply_policy_list" android:title="@string/sk_list_replies_policy_list" />
|
||||
<item android:id="@+id/reply_policy_followed" android:title="@string/sk_list_replies_policy_followed" />
|
||||
<item android:id="@+id/reply_policy_none" android:title="@string/sk_list_replies_policy_none" />
|
||||
</menu>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/create"
|
||||
android:title="@string/sk_create"
|
||||
android:icon="@drawable/ic_fluent_channel_add_24_regular"
|
||||
android:showAsAction="always" />
|
||||
</menu>
|
|
@ -144,6 +144,13 @@
|
|||
<string name="sk_mark_as_read">Mark as read</string>
|
||||
<string name="sk_settings_about_instance">About instance</string>
|
||||
<string name="sk_settings_single_notification">Only show one notification</string>
|
||||
<string name="sk_create">Create</string>
|
||||
<string name="sk_create_list_title">Create list</string>
|
||||
<string name="sk_list_name_hint">List name</string>
|
||||
<string name="sk_list_replies_policy">Show replies to</string>
|
||||
<string name="sk_list_replies_policy_list">List members</string>
|
||||
<string name="sk_list_replies_policy_followed">Any followed user</string>
|
||||
<string name="sk_list_replies_policy_none">No one</string>
|
||||
|
||||
<!-- accessibility labels-->
|
||||
<string name="sk_poll_option_add">Add new poll option</string>
|
||||
|
|
Loading…
Reference in New Issue