Merge remote-tracking branch 'megalodon_main/main'
# Conflicts: # mastodon/build.gradle # mastodon/src/main/java/org/joinmastodon/android/ui/CustomEmojiPopupKeyboard.java # mastodon/src/main/res/values-pt-rBR/strings_sk.xml # mastodon/src/main/res/values-ro-rRO/strings_sk.xml
This commit is contained in:
@@ -51,50 +51,7 @@ public class MainActivity extends FragmentStackActivity implements ProvidesAssis
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if(savedInstanceState==null){
|
||||
if(AccountSessionManager.getInstance().getLoggedInAccounts().isEmpty()){
|
||||
showFragmentClearingBackStack(new CustomWelcomeFragment());
|
||||
}else{
|
||||
AccountSession session;
|
||||
Bundle args=new Bundle();
|
||||
Intent intent=getIntent();
|
||||
if(intent.hasExtra("fromExternalShare")) {
|
||||
AccountSessionManager.getInstance()
|
||||
.setLastActiveAccountID(intent.getStringExtra("account"));
|
||||
AccountSessionManager.getInstance().maybeUpdateLocalInfo(
|
||||
AccountSessionManager.getInstance().getLastActiveAccount());
|
||||
showFragmentForExternalShare(intent.getExtras());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean fromNotification = intent.getBooleanExtra("fromNotification", false);
|
||||
boolean hasNotification = intent.hasExtra("notification");
|
||||
if(fromNotification){
|
||||
String accountID=intent.getStringExtra("accountID");
|
||||
try{
|
||||
session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
if(!hasNotification) args.putString("tab", "notifications");
|
||||
}catch(IllegalStateException x){
|
||||
session=AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
}
|
||||
}else{
|
||||
session=AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
}
|
||||
AccountSessionManager.getInstance().maybeUpdateLocalInfo(session);
|
||||
args.putString("account", session.getID());
|
||||
Fragment fragment=session.activated ? new HomeFragment() : new AccountActivationFragment();
|
||||
fragment.setArguments(args);
|
||||
if(fromNotification && hasNotification){
|
||||
Notification notification=Parcels.unwrap(intent.getParcelableExtra("notification"));
|
||||
showFragmentForNotification(notification, session.getID());
|
||||
} else if (intent.getBooleanExtra("compose", false)){
|
||||
showCompose();
|
||||
} else if (Intent.ACTION_VIEW.equals(intent.getAction())){
|
||||
handleURL(intent.getData(), null);
|
||||
} else {
|
||||
showFragmentClearingBackStack(fragment);
|
||||
maybeRequestNotificationsPermission();
|
||||
}
|
||||
}
|
||||
restartHomeFragment();
|
||||
}
|
||||
|
||||
if(GithubSelfUpdater.needSelfUpdating()){
|
||||
@@ -285,4 +242,51 @@ public class MainActivity extends FragmentStackActivity implements ProvidesAssis
|
||||
Fragment fragment = getCurrentFragment();
|
||||
if (fragment != null) callFragmentToProvideAssistContent(fragment, assistContent);
|
||||
}
|
||||
|
||||
public void restartHomeFragment(){
|
||||
if(AccountSessionManager.getInstance().getLoggedInAccounts().isEmpty()){
|
||||
showFragmentClearingBackStack(new CustomWelcomeFragment());
|
||||
}else{
|
||||
AccountSession session;
|
||||
Bundle args=new Bundle();
|
||||
Intent intent=getIntent();
|
||||
if(intent.hasExtra("fromExternalShare")) {
|
||||
AccountSessionManager.getInstance()
|
||||
.setLastActiveAccountID(intent.getStringExtra("account"));
|
||||
AccountSessionManager.getInstance().maybeUpdateLocalInfo(
|
||||
AccountSessionManager.getInstance().getLastActiveAccount());
|
||||
showFragmentForExternalShare(intent.getExtras());
|
||||
return;
|
||||
}
|
||||
|
||||
boolean fromNotification = intent.getBooleanExtra("fromNotification", false);
|
||||
boolean hasNotification = intent.hasExtra("notification");
|
||||
if(fromNotification){
|
||||
String accountID=intent.getStringExtra("accountID");
|
||||
try{
|
||||
session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
if(!hasNotification) args.putString("tab", "notifications");
|
||||
}catch(IllegalStateException x){
|
||||
session=AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
}
|
||||
}else{
|
||||
session=AccountSessionManager.getInstance().getLastActiveAccount();
|
||||
}
|
||||
AccountSessionManager.getInstance().maybeUpdateLocalInfo(session);
|
||||
args.putString("account", session.getID());
|
||||
Fragment fragment=session.activated ? new HomeFragment() : new AccountActivationFragment();
|
||||
fragment.setArguments(args);
|
||||
if(fromNotification && hasNotification){
|
||||
Notification notification=Parcels.unwrap(intent.getParcelableExtra("notification"));
|
||||
showFragmentForNotification(notification, session.getID());
|
||||
} else if (intent.getBooleanExtra("compose", false)){
|
||||
showCompose();
|
||||
} else if (Intent.ACTION_VIEW.equals(intent.getAction())){
|
||||
handleURL(intent.getData(), null);
|
||||
} else {
|
||||
showFragmentClearingBackStack(fragment);
|
||||
maybeRequestNotificationsPermission();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,9 +165,7 @@ public class AccountActivationFragment extends ToolbarFragment{
|
||||
private void tryGetAccount(){
|
||||
if(AccountSessionManager.getInstance().tryGetAccount(accountID)==null){
|
||||
uiHandler.removeCallbacks(pollRunnable);
|
||||
getActivity().finish();
|
||||
Intent intent=new Intent(getActivity(), MainActivity.class);
|
||||
startActivity(intent);
|
||||
((MainActivity)getActivity()).restartHomeFragment();
|
||||
return;
|
||||
}
|
||||
currentRequest=new GetOwnAccount()
|
||||
|
||||
@@ -163,9 +163,7 @@ public class SettingsMainFragment extends BaseSettingsFragment<Void>{
|
||||
.setMessage(getString(R.string.confirm_log_out, session.getFullUsername()))
|
||||
.setPositiveButton(R.string.log_out, (dialog, which)->account.logOut(getActivity(), ()->{
|
||||
loggedOut=true;
|
||||
getActivity().finish();
|
||||
Intent intent=new Intent(getActivity(), MainActivity.class);
|
||||
startActivity(intent);
|
||||
((MainActivity)getActivity()).restartHomeFragment();
|
||||
}))
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.joinmastodon.android.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EmojiCategory{
|
||||
@@ -10,4 +11,8 @@ public class EmojiCategory{
|
||||
this.title=title;
|
||||
this.emojis=emojis;
|
||||
}
|
||||
public EmojiCategory(EmojiCategory category){
|
||||
this.title = category.title;
|
||||
this.emojis = new ArrayList<>(category.emojis);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.graphics.drawable.Animatable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
@@ -39,6 +40,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import me.grishka.appkit.FragmentStackActivity;
|
||||
import me.grishka.appkit.Nav;
|
||||
import me.grishka.appkit.api.Callback;
|
||||
import me.grishka.appkit.api.ErrorResponse;
|
||||
@@ -145,21 +147,10 @@ public class AccountSwitcherSheet extends BottomSheet{
|
||||
}
|
||||
|
||||
private void logOut(String accountID){
|
||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||
new RevokeOauthToken(session.app.clientId, session.app.clientSecret, session.token.accessToken)
|
||||
.setCallback(new Callback<>(){
|
||||
@Override
|
||||
public void onSuccess(Object result){
|
||||
onLoggedOut(accountID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
onLoggedOut(accountID);
|
||||
}
|
||||
})
|
||||
.wrapProgress(activity, R.string.loading, false)
|
||||
.exec(accountID);
|
||||
AccountSessionManager.get(accountID).logOut(activity, ()->{
|
||||
dismiss();
|
||||
((MainActivity)activity).restartHomeFragment();
|
||||
});
|
||||
}
|
||||
|
||||
private void logOutAll(){
|
||||
@@ -327,15 +318,15 @@ public class AccountSwitcherSheet extends BottomSheet{
|
||||
@Override
|
||||
public void onClick(){
|
||||
setOnDismissListener(null);
|
||||
dismiss();
|
||||
if (onClick != null) {
|
||||
dismiss();
|
||||
onClick.accept(item.getID(), false);
|
||||
return;
|
||||
}
|
||||
if(AccountSessionManager.getInstance().tryGetAccount(item.getID())!=null)
|
||||
if(AccountSessionManager.getInstance().tryGetAccount(item.getID())!=null){
|
||||
AccountSessionManager.getInstance().setLastActiveAccountID(item.getID());
|
||||
activity.finish();
|
||||
activity.startActivity(new Intent(activity, MainActivity.class));
|
||||
((MainActivity)activity).restartHomeFragment();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,6 +17,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Filter;
|
||||
import android.widget.Filterable;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
@@ -35,6 +37,7 @@ import org.joinmastodon.android.model.Emoji;
|
||||
import org.joinmastodon.android.model.EmojiCategory;
|
||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -158,43 +161,52 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun
|
||||
|
||||
ll.addView(list, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
|
||||
|
||||
FrameLayout bottomPanel=new FrameLayout(activity);
|
||||
bottomPanel.setPadding(V.dp(16), V.dp(8), V.dp(16), V.dp(8));
|
||||
bottomPanel.setBackgroundResource(R.drawable.bg_m3_surface2);
|
||||
ll.addView(bottomPanel, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
if(forReaction){
|
||||
InputMethodManager imm=(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
FrameLayout topPanel=new FrameLayout(activity);
|
||||
topPanel.setPadding(V.dp(16), V.dp(12), V.dp(16), V.dp(12));
|
||||
topPanel.setBackgroundResource(R.drawable.bg_m3_surface2);
|
||||
ll.addView(topPanel, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
// TODO: support filtering custom emoji
|
||||
InputMethodManager imm=(InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
EditText input=new EditText(activity);
|
||||
input.setHint(R.string.sk_enter_emoji_hint);
|
||||
input.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
if (!s.toString().isEmpty()) {
|
||||
if (emojiRegex.matcher(s.toString()).find()) {
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count){
|
||||
// Only check the emoji regex if the text field was empty before
|
||||
if(start == 0){
|
||||
if(emojiRegex.matcher(s.toString()).find()){
|
||||
imm.hideSoftInputFromWindow(input.getWindowToken(), 0);
|
||||
listener.onEmojiSelected(s.toString().substring(before));
|
||||
input.getText().clear();
|
||||
} else {
|
||||
Toast.makeText(activity, R.string.sk_enter_emoji_toast, Toast.LENGTH_SHORT).show();
|
||||
input.getText().clear();
|
||||
}
|
||||
}
|
||||
for(int i=0; i<adapter.getAdapterCount(); i++){
|
||||
SingleCategoryAdapter currentAdapter=(SingleCategoryAdapter) adapter.getAdapterAt(i);
|
||||
currentAdapter.getFilter().filter(s.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
|
||||
@Override public void afterTextChanged(Editable s) {}
|
||||
});
|
||||
input.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener(){
|
||||
@Override
|
||||
public void onViewAttachedToWindow(@NonNull View view){}
|
||||
|
||||
FrameLayout.LayoutParams params=new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START);
|
||||
int pad=forReaction ? 0 : V.dp(36 + 16);
|
||||
params.setMargins(pad, V.dp(8), pad, V.dp(8));
|
||||
bottomPanel.addView(input, params);
|
||||
}
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(@NonNull View view){
|
||||
input.getText().clear();
|
||||
}
|
||||
});
|
||||
topPanel.addView(input);
|
||||
|
||||
}else{ // in compose fragment
|
||||
FrameLayout bottomPanel=new FrameLayout(activity);
|
||||
bottomPanel.setPadding(V.dp(16), V.dp(8), V.dp(16), V.dp(8));
|
||||
bottomPanel.setBackgroundResource(R.drawable.bg_m3_surface2);
|
||||
ll.addView(bottomPanel, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
if(!forReaction){
|
||||
ImageButton hideKeyboard=new ImageButton(activity);
|
||||
hideKeyboard.setImageResource(R.drawable.ic_fluent_keyboard_dock_24_regular);
|
||||
hideKeyboard.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(activity, R.attr.colorM3OnSurfaceVariant)));
|
||||
@@ -236,13 +248,16 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun
|
||||
return accountID;
|
||||
}
|
||||
|
||||
private class SingleCategoryAdapter extends UsableRecyclerView.Adapter<RecyclerView.ViewHolder> implements ImageLoaderRecyclerAdapter{
|
||||
private final EmojiCategory category;
|
||||
private final List<ImageLoaderRequest> requests;
|
||||
private class SingleCategoryAdapter extends UsableRecyclerView.Adapter<RecyclerView.ViewHolder> implements ImageLoaderRecyclerAdapter, Filterable{
|
||||
private EmojiCategory category;
|
||||
|
||||
private final EmojiCategory originalCategory;
|
||||
private List<ImageLoaderRequest> requests;
|
||||
|
||||
public SingleCategoryAdapter(EmojiCategory category){
|
||||
super(imgLoader);
|
||||
this.category=category;
|
||||
this.originalCategory=new EmojiCategory(category);
|
||||
requests=category.emojis.stream().map(e->new UrlImageLoaderRequest(e.getUrl(playGifs), V.dp(24), V.dp(24))).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@@ -254,17 +269,22 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position){
|
||||
if(category.emojis.size() == 0) {
|
||||
holder.itemView.setVisibility(View.GONE);
|
||||
}
|
||||
if(holder instanceof EmojiViewHolder evh){
|
||||
evh.bind(category.emojis.get(position-1));
|
||||
evh.positionWithinCategory=position-1;
|
||||
}else if(holder instanceof SectionHeaderViewHolder shvh){
|
||||
shvh.bind(TextUtils.isEmpty(category.title) ? domain : category.title);
|
||||
}
|
||||
|
||||
super.onBindViewHolder(holder, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount(){
|
||||
if(category.emojis.size() == 0) return 0;
|
||||
return category.emojis.size()+1;
|
||||
}
|
||||
|
||||
@@ -282,6 +302,39 @@ public class CustomEmojiPopupKeyboard extends PopupKeyboard implements HasAccoun
|
||||
public ImageLoaderRequest getImageRequest(int position, int image){
|
||||
return requests.get(position-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Filter getFilter(){
|
||||
return emojiFilter;
|
||||
}
|
||||
private final Filter emojiFilter = new Filter(){
|
||||
@Override
|
||||
protected FilterResults performFiltering(CharSequence charSequence){
|
||||
List<Emoji> filteredEmoji=new ArrayList<>();
|
||||
String search=charSequence.toString().toLowerCase().trim();
|
||||
|
||||
if(charSequence==null || charSequence.length()==0){
|
||||
filteredEmoji.addAll(originalCategory.emojis);
|
||||
}else{
|
||||
for(Emoji emoji : originalCategory.emojis){
|
||||
if(emoji.shortcode.toLowerCase().contains(search)){
|
||||
filteredEmoji.add(emoji);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
FilterResults results=new FilterResults();
|
||||
results.values=filteredEmoji;
|
||||
return results;
|
||||
}
|
||||
@Override
|
||||
protected void publishResults(CharSequence charSequence, FilterResults filterResults){
|
||||
category.emojis.clear();
|
||||
category.emojis.addAll((List) filterResults.values);
|
||||
requests=category.emojis.stream().map(e->new UrlImageLoaderRequest(e.getUrl(playGifs), V.dp(24), V.dp(24))).collect(Collectors.toList());
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private class SectionHeaderViewHolder extends BindableViewHolder<String> implements StickyHeadersOverlay.HeaderViewHolder{
|
||||
|
||||
Reference in New Issue
Block a user