Skip to content

Commit

Permalink
Merge remote-tracking branch 'megalodon_main/main'
Browse files Browse the repository at this point in the history
# 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
  • Loading branch information
LucasGGamerM committed Oct 1, 2023
2 parents c7017c1 + 1988849 commit 6f180c0
Show file tree
Hide file tree
Showing 12 changed files with 461 additions and 108 deletions.
92 changes: 48 additions & 44 deletions mastodon/src/main/java/org/joinmastodon/android/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,50 +51,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState){
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()){
Expand Down Expand Up @@ -285,4 +242,51 @@ public void onProvideAssistContent(AssistContent assistContent) {
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();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ public void onError(ErrorResponse error){
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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,7 @@ private void onLogOutClick(){
.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();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.joinmastodon.android.model;

import java.util.ArrayList;
import java.util.List;

public class EmojiCategory{
Expand All @@ -10,4 +11,8 @@ public EmojiCategory(String title, List<Emoji> emojis){
this.title=title;
this.emojis=emojis;
}
public EmojiCategory(EmojiCategory category){
this.title = category.title;
this.emojis = new ArrayList<>(category.emojis);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
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;
Expand Down Expand Up @@ -39,6 +40,7 @@
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;
Expand Down Expand Up @@ -145,21 +147,10 @@ private void confirmLogOutAll(){
}

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(){
Expand Down Expand Up @@ -327,15 +318,15 @@ private void onExtraBtnClick(View view) {
@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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
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;
Expand All @@ -35,6 +37,7 @@
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;
Expand Down Expand Up @@ -158,43 +161,52 @@ public boolean onInterceptTouchEvent(MotionEvent e){

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)));
Expand Down Expand Up @@ -236,13 +248,16 @@ public String getAccountID(){
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());
}

Expand All @@ -254,17 +269,22 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int

@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;
}

Expand All @@ -282,6 +302,39 @@ public int getImageCountForItem(int position){
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{
Expand Down
16 changes: 16 additions & 0 deletions mastodon/src/main/res/values-ar/strings_sk.xml
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,20 @@
<string name="sk_enter_emoji_toast">يُرجى إدخال إيموجي</string>
<string name="sk_in_reply">ردّا على</string>
<string name="sk_open_in_app_failed">لا يمكن فتحه في التطبيق</string>
<string name="sk_settings_enable_delete_notifications">تمكين حذف الإشعارات</string>
<string name="sk_clear_all_notifications_confirm">أتريد حقا حذف كافة الإشعارات؟</string>
<string name="sk_already_bookmarked">موجود بالفعل في الفواصل المرجعية</string>
<string name="sk_resource_not_found">المَورِد غير موجود</string>
<string name="sk_delete_notification_confirm">أتريد حقا حذف هذا الإشعار؟</string>
<string name="sk_draft_or_schedule">تحرير مسودة أو برمجتها</string>
<string name="sk_trending_links_info_banner">هذه هي القصص الإخبارية التي يُتَحدّث عنها في خادمكم.</string>
<string name="sk_notification_type_posts">إشعارات المنشورات</string>
<string name="sk_confirm_delete_draft">هل أنت متأكد من أنك تريد حذف مُسودّة هذا المنشور؟</string>
<string name="sk_compose_no_schedule">لا تُبرمِجه</string>
<string name="sk_confirm_clear_recent_languages">أتريد حقا مسح لغاتك المُستخدَمة حديثا؟</string>
<string name="sk_confirm_delete_scheduled_post">هل أنت متأكد من أنك تريد حذف هذا المنشور المُبرمَج؟</string>
<string name="sk_trending_posts_info_banner">هذه هي المنشورات المثيرة للإهتمام على خادمكم.</string>
<string name="sk_federated_timeline_info_banner">هذه هي أحدث المنشورات للأعضاء في فديراليتك.</string>
<string name="sk_bubble_timeline_info_banner">هذه هي أحدث المنشورات على الشبكة والتي انتقاها مُدراء خادمكم.</string>
<string name="sk_schedule_or_draft">برمجة أو تحرير مُسودّة</string>
</resources>
Loading

0 comments on commit 6f180c0

Please sign in to comment.