mirror of https://codeberg.org/tom79/Fedilab
parent
170dbbd0cf
commit
cdbfb17d94
@ -0,0 +1,202 @@
|
||||
package app.fedilab.android.activities;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputFilter;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.client.entities.api.Tag;
|
||||
import app.fedilab.android.client.entities.app.Timeline;
|
||||
import app.fedilab.android.databinding.ActivityFollowedTagsBinding;
|
||||
import app.fedilab.android.databinding.PopupAddFollowedTagtBinding;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.ThemeHelper;
|
||||
import app.fedilab.android.ui.drawer.FollowedTagAdapter;
|
||||
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline;
|
||||
import app.fedilab.android.viewmodel.mastodon.TagVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
||||
public class FollowedTagActivity extends BaseActivity implements FollowedTagAdapter.ActionOnTag {
|
||||
|
||||
|
||||
private ActivityFollowedTagsBinding binding;
|
||||
private boolean canGoBack;
|
||||
private TagVM tagVM;
|
||||
private Tag tag;
|
||||
private ArrayList<Tag> tagList;
|
||||
private FollowedTagAdapter followedTagAdapter;
|
||||
private FragmentMastodonTimeline fragmentMastodonTimeline;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeHelper.applyThemeBar(this);
|
||||
binding = ActivityFollowedTagsBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
canGoBack = false;
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
|
||||
}
|
||||
tagVM = new ViewModelProvider(FollowedTagActivity.this).get(TagVM.class);
|
||||
tagVM.followedTags(BaseMainActivity.currentInstance, BaseMainActivity.currentToken)
|
||||
.observe(FollowedTagActivity.this, tags -> {
|
||||
if (tags != null && tags.tags != null && tags.tags.size() > 0) {
|
||||
tagList = new ArrayList<>(tags.tags);
|
||||
followedTagAdapter = new FollowedTagAdapter(tagList);
|
||||
followedTagAdapter.actionOnTag = this;
|
||||
binding.notContent.setVisibility(View.GONE);
|
||||
binding.recyclerView.setAdapter(followedTagAdapter);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(FollowedTagActivity.this));
|
||||
} else {
|
||||
binding.notContent.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_unfollow && tag != null) {
|
||||
AlertDialog.Builder alt_bld = new AlertDialog.Builder(FollowedTagActivity.this, Helper.dialogStyle());
|
||||
alt_bld.setTitle(R.string.action_unfollow_tag);
|
||||
alt_bld.setMessage(R.string.action_unfollow_tag_confirm);
|
||||
alt_bld.setPositiveButton(R.string.unfollow, (dialog, id) -> {
|
||||
tagVM.unfollow(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, tag.name);
|
||||
int position = 0;
|
||||
for (Tag tagTmp : tagList) {
|
||||
if (tagTmp.name.equalsIgnoreCase(tag.name)) {
|
||||
break;
|
||||
}
|
||||
position++;
|
||||
}
|
||||
tagList.remove(position);
|
||||
followedTagAdapter.notifyItemRemoved(position);
|
||||
ThemeHelper.slideViewsToRight(binding.fragmentContainer, binding.recyclerView, () -> {
|
||||
canGoBack = false;
|
||||
if (fragmentMastodonTimeline != null) {
|
||||
fragmentMastodonTimeline.onDestroyView();
|
||||
}
|
||||
invalidateOptionsMenu();
|
||||
setTitle(R.string.action_lists);
|
||||
});
|
||||
if (tagList.size() == 0) {
|
||||
binding.notContent.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.notContent.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
alt_bld.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
|
||||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
} else if (item.getItemId() == R.id.action_follow_tag) {
|
||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(FollowedTagActivity.this, Helper.dialogStyle());
|
||||
PopupAddFollowedTagtBinding popupAddFollowedTagtBinding = PopupAddFollowedTagtBinding.inflate(getLayoutInflater());
|
||||
dialogBuilder.setView(popupAddFollowedTagtBinding.getRoot());
|
||||
popupAddFollowedTagtBinding.addTag.setFilters(new InputFilter[]{new InputFilter.LengthFilter(255)});
|
||||
dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
|
||||
if (popupAddFollowedTagtBinding.addTag.getText() != null && popupAddFollowedTagtBinding.addTag.getText().toString().trim().length() > 0) {
|
||||
tagVM.follow(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, popupAddFollowedTagtBinding.addTag.getText().toString().trim())
|
||||
.observe(FollowedTagActivity.this, newTag -> {
|
||||
if (tagList == null) {
|
||||
tagList = new ArrayList<>();
|
||||
}
|
||||
if (newTag != null && followedTagAdapter != null) {
|
||||
tagList.add(0, newTag);
|
||||
followedTagAdapter.notifyItemInserted(0);
|
||||
} else {
|
||||
Toasty.error(FollowedTagActivity.this, getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
dialog.dismiss();
|
||||
} else {
|
||||
popupAddFollowedTagtBinding.addTag.setError(getString(R.string.not_valid_tag_name));
|
||||
}
|
||||
|
||||
});
|
||||
dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
|
||||
dialogBuilder.create().show();
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(@NonNull Menu menu) {
|
||||
if (!canGoBack) {
|
||||
getMenuInflater().inflate(R.menu.menu_main_followed_tag, menu);
|
||||
} else {
|
||||
getMenuInflater().inflate(R.menu.menu_followed_tag, menu);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (canGoBack) {
|
||||
canGoBack = false;
|
||||
ThemeHelper.slideViewsToRight(binding.fragmentContainer, binding.recyclerView, () -> {
|
||||
if (fragmentMastodonTimeline != null) {
|
||||
fragmentMastodonTimeline.onDestroyView();
|
||||
}
|
||||
});
|
||||
setTitle(R.string.action_lists);
|
||||
invalidateOptionsMenu();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(Tag tag) {
|
||||
this.tag = tag;
|
||||
canGoBack = true;
|
||||
ThemeHelper.slideViewsToLeft(binding.recyclerView, binding.fragmentContainer, () -> {
|
||||
fragmentMastodonTimeline = new FragmentMastodonTimeline();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putSerializable(Helper.ARG_SEARCH_KEYWORD, tag.name);
|
||||
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TAG);
|
||||
setTitle(tag.name);
|
||||
fragmentMastodonTimeline.setArguments(bundle);
|
||||
FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
FragmentTransaction fragmentTransaction =
|
||||
fragmentManager.beginTransaction();
|
||||
fragmentTransaction.replace(R.id.fragment_container, fragmentMastodonTimeline);
|
||||
fragmentTransaction.commit();
|
||||
invalidateOptionsMenu();
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package app.fedilab.android.ui.drawer;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.client.entities.api.Tag;
|
||||
import app.fedilab.android.databinding.DrawerListBinding;
|
||||
|
||||
|
||||
public class FollowedTagAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private final List<Tag> tagList;
|
||||
public ActionOnTag actionOnTag;
|
||||
|
||||
public FollowedTagAdapter(List<Tag> tagList) {
|
||||
this.tagList = tagList;
|
||||
}
|
||||
|
||||
|
||||
public int getCount() {
|
||||
return tagList.size();
|
||||
}
|
||||
|
||||
public Tag getItem(int position) {
|
||||
return tagList.get(position);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
DrawerListBinding itemBinding = DrawerListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new ListViewHolder(itemBinding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||
Tag tag = tagList.get(position);
|
||||
ListViewHolder holder = (ListViewHolder) viewHolder;
|
||||
holder.binding.title.setText(tag.name);
|
||||
holder.binding.title.setOnClickListener(v -> actionOnTag.click(tag));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return tagList.size();
|
||||
}
|
||||
|
||||
|
||||
public interface ActionOnTag {
|
||||
void click(Tag tag);
|
||||
}
|
||||
|
||||
public static class ListViewHolder extends RecyclerView.ViewHolder {
|
||||
DrawerListBinding binding;
|
||||
|
||||
ListViewHolder(DrawerListBinding itemView) {
|
||||
super(itemView.getRoot());
|
||||
binding = itemView;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M17,19.22H5V7h7V5H5C3.9,5 3,5.9 3,7v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-7h-2V19.22z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,2h-2v3h-3c0.01,0.01 0,2 0,2h3v2.99c0.01,0.01 2,0 2,0V7h3V5h-3V2z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,9h8v2h-8z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,12l0,2l8,0l0,-2l-3,0z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,15h8v2h-8z" />
|
||||
</vector>
|
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,10L20,8h-4L16,4h-2v4h-4L10,4L8,4v4L4,8v2h4v4L4,14v2h4v4h2v-4h4v4h2v-4h4v-2h-4v-4h4zM14,14h-4v-4h4v4z" />
|
||||
</vector>
|
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/fab_margin">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:scrollbars="none" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/not_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:padding="10dp"
|
||||
android:text="@string/action_followed_tag_empty"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:typeface="serif"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
</RelativeLayout>
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/add_tag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:hint="@string/write_the_tag_to_follow"
|
||||
android:inputType="text"
|
||||
android:singleLine="true" />
|
||||
</LinearLayout>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_unfollow"
|
||||
android:icon="@drawable/ic_baseline_delete_24"
|
||||
android:title="@string/action_unfollow_tag"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_follow_tag"
|
||||
android:icon="@drawable/ic_baseline_post_add_24"
|
||||
android:title="@string/follow_tag"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_add_timeline"
|
||||
android:icon="@drawable/ic_baseline_add_24"
|
||||
android:title="@string/add_instances"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_follow_tag"
|
||||
android:icon="@drawable/ic_baseline_post_add_24"
|
||||
android:title="@string/action_tag_follow"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
Loading…
Reference in new issue