forked from mirrors/Fedilab
Instance directory
This commit is contained in:
parent
e03c02cc35
commit
d5a5f08727
14 changed files with 230 additions and 2 deletions
|
@ -249,6 +249,11 @@
|
|||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/Suggestions"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
<activity
|
||||
android:name=".activities.DirectoryActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/Directory"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
<activity
|
||||
android:name=".activities.PartnerShipActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
|
|
|
@ -109,6 +109,7 @@ import app.fedilab.android.activities.BaseActivity;
|
|||
import app.fedilab.android.activities.CacheActivity;
|
||||
import app.fedilab.android.activities.ComposeActivity;
|
||||
import app.fedilab.android.activities.ContextActivity;
|
||||
import app.fedilab.android.activities.DirectoryActivity;
|
||||
import app.fedilab.android.activities.DraftActivity;
|
||||
import app.fedilab.android.activities.FilterActivity;
|
||||
import app.fedilab.android.activities.FollowRequestActivity;
|
||||
|
@ -409,6 +410,9 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
} else if (id == R.id.nav_suggestions) {
|
||||
Intent intent = new Intent(this, SuggestionActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_directory) {
|
||||
Intent intent = new Intent(this, DirectoryActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_cache) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, CacheActivity.class);
|
||||
startActivity(intent);
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
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 static app.fedilab.android.client.entities.app.Timeline.TimeLineEnum.ACCOUNT_DIRECTORY;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.ActivityDirectoryBinding;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonAccount;
|
||||
|
||||
|
||||
public class DirectoryActivity extends BaseBarActivity {
|
||||
|
||||
private static boolean local = false;
|
||||
private static String order = "active";
|
||||
private FragmentMastodonAccount fragmentMastodonAccount;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
ActivityDirectoryBinding binding = ActivityDirectoryBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
fragmentMastodonAccount = new FragmentMastodonAccount();
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(Helper.ARG_DIRECTORY_LOCAL, local);
|
||||
bundle.putString(Helper.ARG_DIRECTORY_ORDER, order);
|
||||
bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, ACCOUNT_DIRECTORY);
|
||||
Helper.addFragment(getSupportFragmentManager(), R.id.nav_host_fragment_directory, fragmentMastodonAccount, bundle, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_directory, menu);
|
||||
if (order.equals("active")) {
|
||||
menu.findItem(R.id.order_active).setChecked(true);
|
||||
} else {
|
||||
menu.findItem(R.id.order_new).setChecked(true);
|
||||
}
|
||||
menu.findItem(R.id.action_local).setChecked(local);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NotNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_local) {
|
||||
item.setChecked(!item.isChecked());
|
||||
local = item.isChecked();
|
||||
} else if (item.getItemId() == R.id.order_active) {
|
||||
order = "active";
|
||||
} else if (item.getItemId() == R.id.order_new) {
|
||||
order = "new";
|
||||
}
|
||||
recreate();
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
}
|
|
@ -417,4 +417,15 @@ public interface MastodonAccountsService {
|
|||
@Header("Authorization") String token,
|
||||
@Path("account_id") String account_id
|
||||
);
|
||||
|
||||
|
||||
//Get user suggestions
|
||||
@GET("directory")
|
||||
Call<List<Account>> getDirectory(
|
||||
@Header("Authorization") String token,
|
||||
@Query("offset") Integer offset,
|
||||
@Query("limit") Integer limit,
|
||||
@Query("order") String order,
|
||||
@Query("local") Boolean local
|
||||
);
|
||||
}
|
||||
|
|
|
@ -382,6 +382,8 @@ public class Timeline {
|
|||
TREND_MESSAGE("TREND_MESSAGE"),
|
||||
@SerializedName("ACCOUNT_SUGGESTION")
|
||||
ACCOUNT_SUGGESTION("ACCOUNT_SUGGESTION"),
|
||||
@SerializedName("ACCOUNT_DIRECTORY")
|
||||
ACCOUNT_DIRECTORY("ACCOUNT_DIRECTORY"),
|
||||
@SerializedName("PUBLIC_TREND_MESSAGE")
|
||||
TREND_MESSAGE_PUBLIC("TREND_MESSAGE_PUBLIC"),
|
||||
@SerializedName("STATUS_HISTORY")
|
||||
|
|
|
@ -253,6 +253,8 @@ public class Helper {
|
|||
public static final String ARG_WORK_ID = "ARG_WORK_ID";
|
||||
public static final String ARG_LIST_ID = "ARG_LIST_ID";
|
||||
public static final String ARG_SEARCH_KEYWORD = "ARG_SEARCH_KEYWORD";
|
||||
public static final String ARG_DIRECTORY_ORDER = "ARG_DIRECTORY_ORDER";
|
||||
public static final String ARG_DIRECTORY_LOCAL = "ARG_DIRECTORY_LOCAL";
|
||||
public static final String ARG_SEARCH_TYPE = "ARG_SEARCH_TYPE";
|
||||
public static final String ARG_SEARCH_KEYWORD_CACHE = "ARG_SEARCH_KEYWORD_CACHE";
|
||||
public static final String ARG_VIEW_MODEL_KEY = "ARG_VIEW_MODEL_KEY";
|
||||
|
|
|
@ -15,6 +15,8 @@ package app.fedilab.android.ui.fragment.timeline;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import static app.fedilab.android.helper.MastodonHelper.ACCOUNTS_PER_CALL;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -63,6 +65,8 @@ public class FragmentMastodonAccount extends Fragment {
|
|||
private FedilabProfileTLPageAdapter.follow_type followType;
|
||||
private String viewModelKey;
|
||||
private Timeline.TimeLineEnum timelineType;
|
||||
private String order;
|
||||
private Boolean local;
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
@ -72,6 +76,8 @@ public class FragmentMastodonAccount extends Fragment {
|
|||
followType = (FedilabProfileTLPageAdapter.follow_type) getArguments().getSerializable(Helper.ARG_FOLLOW_TYPE);
|
||||
viewModelKey = getArguments().getString(Helper.ARG_VIEW_MODEL_KEY, "");
|
||||
timelineType = (Timeline.TimeLineEnum) getArguments().get(Helper.ARG_TIMELINE_TYPE);
|
||||
order = getArguments().getString(Helper.ARG_DIRECTORY_ORDER, "active");
|
||||
local = getArguments().getBoolean(Helper.ARG_DIRECTORY_LOCAL, false);
|
||||
}
|
||||
flagLoading = false;
|
||||
binding = FragmentPaginationBinding.inflate(inflater, container, false);
|
||||
|
@ -159,7 +165,15 @@ public class FragmentMastodonAccount extends Fragment {
|
|||
.observe(getViewLifecycleOwner(), this::initializeAccountCommonView);
|
||||
} else {
|
||||
accountsVM.getBlocks(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, String.valueOf(MastodonHelper.accountsPerCall(requireActivity())), max_id, null)
|
||||
.observe(getViewLifecycleOwner(), this::dealWithPagination);
|
||||
}
|
||||
} else if (timelineType == Timeline.TimeLineEnum.ACCOUNT_DIRECTORY) {
|
||||
if (firstLoad) {
|
||||
accountsVM.getDirectory(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, 0, ACCOUNTS_PER_CALL, order, local)
|
||||
.observe(getViewLifecycleOwner(), this::initializeAccountCommonView);
|
||||
} else {
|
||||
accountsVM.getDirectory(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, offset, ACCOUNTS_PER_CALL, order, local)
|
||||
.observe(getViewLifecycleOwner(), this::dealWithPagination);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,8 +237,10 @@ public class FragmentMastodonAccount extends Fragment {
|
|||
|
||||
this.accounts = accounts.accounts;
|
||||
accountAdapter = new AccountAdapter(this.accounts, timelineType == Timeline.TimeLineEnum.MUTED_TIMELINE_HOME);
|
||||
if (search == null) {
|
||||
if (search == null && timelineType != Timeline.TimeLineEnum.ACCOUNT_DIRECTORY) {
|
||||
flagLoading = accounts.pagination.max_id == null;
|
||||
} else if (timelineType != Timeline.TimeLineEnum.ACCOUNT_DIRECTORY) {
|
||||
offset += ACCOUNTS_PER_CALL;
|
||||
} else {
|
||||
offset += MastodonHelper.SEARCH_PER_CALL;
|
||||
}
|
||||
|
@ -288,6 +304,8 @@ public class FragmentMastodonAccount extends Fragment {
|
|||
max_id = fetched_accounts.pagination.max_id;
|
||||
if (search != null) {
|
||||
offset += MastodonHelper.SEARCH_PER_CALL;
|
||||
} else if (timelineType == Timeline.TimeLineEnum.ACCOUNT_DIRECTORY) {
|
||||
offset += ACCOUNTS_PER_CALL;
|
||||
}
|
||||
accountAdapter.notifyItemRangeInserted(startId, fetched_accounts.accounts.size());
|
||||
} else {
|
||||
|
|
|
@ -1595,7 +1595,7 @@ public class AccountsVM extends AndroidViewModel {
|
|||
* Accounts the user has had past positive interactions with, but is not yet following.
|
||||
*
|
||||
* @param limit Maximum number of results to return. Defaults to 40.
|
||||
* @return {@link LiveData} containing a {@link List} of {@link Account}s
|
||||
* @return {@link LiveData} containing a {@link List} of {@link Suggestion}s
|
||||
*/
|
||||
public LiveData<Suggestions> getSuggestions(@NonNull String instance, String token, String limit) {
|
||||
suggestionsMutableLiveData = new MutableLiveData<>();
|
||||
|
@ -1621,6 +1621,37 @@ public class AccountsVM extends AndroidViewModel {
|
|||
return suggestionsMutableLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* List accounts visible in the directory.
|
||||
*
|
||||
* @param limit Maximum number of results to return. Defaults to 40.
|
||||
* @return {@link LiveData} containing a {@link List} of {@link Account}s
|
||||
*/
|
||||
public LiveData<Accounts> getDirectory(@NonNull String instance, String token, Integer offset, Integer limit, String order, Boolean local) {
|
||||
accountsMutableLiveData = new MutableLiveData<>();
|
||||
MastodonAccountsService mastodonAccountsService = init(instance);
|
||||
new Thread(() -> {
|
||||
Call<List<Account>> accountsCall = mastodonAccountsService.getDirectory(token, offset, limit, order, local);
|
||||
Accounts accounts = new Accounts();
|
||||
|
||||
if (accountsCall != null) {
|
||||
try {
|
||||
Response<List<Account>> directoryResponse = accountsCall.execute();
|
||||
if (directoryResponse.isSuccessful()) {
|
||||
accounts.pagination = MastodonHelper.getOffSetPagination(directoryResponse.headers());
|
||||
accounts.accounts = directoryResponse.body();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> accountsMutableLiveData.setValue(accounts);
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
return accountsMutableLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an account from follow suggestions.
|
||||
*
|
||||
|
|
|
@ -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="M19,3h-1L18,1h-2v2L8,3L8,1L6,1v2L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,6c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM18,18L6,18v-1c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1z" />
|
||||
</vector>
|
31
app/src/main/res/layout/activity_directory.xml
Normal file
31
app/src/main/res/layout/activity_directory.xml
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
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>.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment_directory"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
</LinearLayout>
|
|
@ -63,6 +63,11 @@
|
|||
android:icon="@drawable/ic_baseline_account_circle_24"
|
||||
android:title="@string/Suggestions"
|
||||
android:visible="true" />
|
||||
<item
|
||||
android:id="@+id/nav_directory"
|
||||
android:icon="@drawable/ic_baseline_perm_contact_calendar_24"
|
||||
android:title="@string/Directory"
|
||||
android:visible="true" />
|
||||
<item
|
||||
android:id="@+id/nav_about_instance"
|
||||
android:icon="@drawable/ic_info_outline_white_24dp"
|
||||
|
|
23
app/src/main/res/menu/menu_directory.xml
Normal file
23
app/src/main/res/menu/menu_directory.xml
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?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">
|
||||
<group
|
||||
android:id="@+id/order"
|
||||
android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/order_active"
|
||||
android:checked="true"
|
||||
android:title="@string/active"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/order_new"
|
||||
android:title="@string/_new"
|
||||
app:showAsAction="never" />
|
||||
</group>
|
||||
<item
|
||||
android:id="@+id/action_local"
|
||||
android:checkable="true"
|
||||
android:title="@string/local"
|
||||
app:actionViewClass="android.widget.CheckBox"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
|
@ -486,6 +486,7 @@
|
|||
<string name="unresolved">Unresolved</string>
|
||||
<string name="remote">Remote</string>
|
||||
<string name="active">Active</string>
|
||||
<string name="_new">New</string>
|
||||
<string name="pending">Pending</string>
|
||||
<string name="disabled">Disabled</string>
|
||||
<string name="suspended">Suspended</string>
|
||||
|
@ -2206,4 +2207,5 @@
|
|||
<string name="set_display_compact_buttons">Compact action buttons</string>
|
||||
<string name="set_display_compact_buttons_description">Buttons at the bottom of messages will not take the whole width</string>
|
||||
<string name="also_followed_by">Followed by:</string>
|
||||
<string name="Directory">Directory</string>
|
||||
</resources>
|
|
@ -1,5 +1,6 @@
|
|||
Added:
|
||||
- Display familiar followers on profiles
|
||||
- Display and filter Instance directory
|
||||
|
||||
Changed:
|
||||
|
||||
|
|
Loading…
Reference in a new issue