mirror of
				https://codeberg.org/tom79/Fedilab.git
				synced 2025-10-20 11:20:16 +03:00 
			
		
		
		
	Add chat view
This commit is contained in:
		
							parent
							
								
									979354dc75
								
							
						
					
					
						commit
						00a2f0b67a
					
				
					 16 changed files with 474 additions and 30 deletions
				
			
		|  | @ -68,13 +68,15 @@ android { | |||
|                     'src/main/res/layouts/mastodon', | ||||
|                     'src/main/res/layouts/peertube', | ||||
|                     'src/main/res/layouts', | ||||
|                     'src/main/layout', | ||||
| 
 | ||||
|                     'src/main/res/drawables/mastodon', | ||||
|                     'src/main/res/drawables/peertube', | ||||
|                     'src/main/res/drawables', | ||||
| 
 | ||||
|                     'src/main/res/menus/mastodon', | ||||
|                     'src/main/res/menus/peertube', | ||||
|                     'src/main/res/menus', | ||||
| 
 | ||||
|                     'src/main/res' | ||||
|             ] | ||||
|         } | ||||
|  |  | |||
|  | @ -196,6 +196,9 @@ | |||
|         <activity | ||||
|             android:name=".mastodon.activities.ContextActivity" | ||||
|             android:configChanges="keyboardHidden|orientation|screenSize" /> | ||||
|         <activity | ||||
|             android:name=".mastodon.activities.DirectMessageActivity" | ||||
|             android:configChanges="keyboardHidden|orientation|screenSize" /> | ||||
|         <activity | ||||
|             android:name=".mastodon.activities.DraftActivity" | ||||
|             android:configChanges="keyboardHidden|orientation|screenSize" /> | ||||
|  |  | |||
|  | @ -0,0 +1,131 @@ | |||
| package app.fedilab.android.mastodon.activities; | ||||
| /* Copyright 2023 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.BaseMainActivity.currentAccount; | ||||
| 
 | ||||
| import android.content.SharedPreferences; | ||||
| import android.os.Bundle; | ||||
| import android.os.Handler; | ||||
| import android.os.Looper; | ||||
| import android.util.TypedValue; | ||||
| import android.view.MenuItem; | ||||
| 
 | ||||
| import androidx.appcompat.app.ActionBar; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.preference.PreferenceManager; | ||||
| 
 | ||||
| import app.fedilab.android.BaseMainActivity; | ||||
| import app.fedilab.android.R; | ||||
| import app.fedilab.android.databinding.ActivityDirectMessageBinding; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Status; | ||||
| import app.fedilab.android.mastodon.client.entities.app.StatusCache; | ||||
| import app.fedilab.android.mastodon.exception.DBException; | ||||
| import app.fedilab.android.mastodon.helper.Helper; | ||||
| import app.fedilab.android.mastodon.helper.MastodonHelper; | ||||
| import app.fedilab.android.mastodon.ui.drawer.StatusAdapter; | ||||
| import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentMastodonDirectMessage; | ||||
| import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM; | ||||
| 
 | ||||
| public class DirectMessageActivity extends BaseActivity implements FragmentMastodonDirectMessage.FirstMessage { | ||||
| 
 | ||||
|     public static boolean expand; | ||||
|     public static boolean displayCW; | ||||
| 
 | ||||
|     Fragment currentFragment; | ||||
|     private Status firstMessage; | ||||
|     private String remote_instance; | ||||
| 
 | ||||
|     @Override | ||||
|     protected void onCreate(Bundle savedInstanceState) { | ||||
|         super.onCreate(savedInstanceState); | ||||
| 
 | ||||
|         ActivityDirectMessageBinding binding = ActivityDirectMessageBinding.inflate(getLayoutInflater()); | ||||
|         setContentView(binding.getRoot()); | ||||
|         setSupportActionBar(binding.toolbar); | ||||
|         ActionBar actionBar = getSupportActionBar(); | ||||
|         //Remove title | ||||
|         if (actionBar != null) { | ||||
|             actionBar.setDisplayShowTitleEnabled(false); | ||||
|         } | ||||
|         binding.title.setText(R.string.context_conversation); | ||||
|         SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(this); | ||||
|         float scale = sharedpreferences.getFloat(getString(R.string.SET_FONT_SCALE), 1.1f); | ||||
|         binding.title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18 * 1.1f / scale); | ||||
| 
 | ||||
|         if (getSupportActionBar() != null) { | ||||
|             getSupportActionBar().setDisplayHomeAsUpEnabled(true); | ||||
|             getSupportActionBar().setDisplayShowHomeEnabled(true); | ||||
|         } | ||||
|         Bundle b = getIntent().getExtras(); | ||||
|         displayCW = sharedpreferences.getBoolean(getString(R.string.SET_EXPAND_CW), false); | ||||
|         Status focusedStatus = null; // or other values | ||||
|         if (b != null) { | ||||
|             focusedStatus = (Status) b.getSerializable(Helper.ARG_STATUS); | ||||
|             remote_instance = b.getString(Helper.ARG_REMOTE_INSTANCE, null); | ||||
|         } | ||||
|         if (focusedStatus == null || currentAccount == null || currentAccount.mastodon_account == null) { | ||||
|             finish(); | ||||
|             return; | ||||
|         } | ||||
|         MastodonHelper.loadPPMastodon(binding.profilePicture, currentAccount.mastodon_account); | ||||
|         Bundle bundle = new Bundle(); | ||||
|         bundle.putSerializable(Helper.ARG_STATUS, focusedStatus); | ||||
|         bundle.putString(Helper.ARG_REMOTE_INSTANCE, remote_instance); | ||||
|         FragmentMastodonDirectMessage FragmentMastodonDirectMessage = new FragmentMastodonDirectMessage(); | ||||
|         FragmentMastodonDirectMessage.firstMessage = this; | ||||
|         currentFragment = Helper.addFragment(getSupportFragmentManager(), R.id.nav_host_fragment_content_main, FragmentMastodonDirectMessage, bundle, null, null); | ||||
|         StatusesVM timelinesVM = new ViewModelProvider(DirectMessageActivity.this).get(StatusesVM.class); | ||||
|         timelinesVM.getStatus(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, focusedStatus.id).observe(DirectMessageActivity.this, status -> { | ||||
|             if (status != null) { | ||||
|                 StatusCache statusCache = new StatusCache(); | ||||
|                 statusCache.instance = BaseMainActivity.currentInstance; | ||||
|                 statusCache.user_id = BaseMainActivity.currentUserID; | ||||
|                 statusCache.status = status; | ||||
|                 statusCache.status_id = status.id; | ||||
|                 //Update cache | ||||
|                 new Thread(() -> { | ||||
|                     try { | ||||
|                         new StatusCache(getApplication()).updateIfExists(statusCache); | ||||
|                         Handler mainHandler = new Handler(Looper.getMainLooper()); | ||||
|                         //Update UI | ||||
|                         Runnable myRunnable = () -> StatusAdapter.sendAction(DirectMessageActivity.this, Helper.ARG_STATUS_ACTION, status, null); | ||||
|                         mainHandler.post(myRunnable); | ||||
|                     } catch (DBException e) { | ||||
|                         e.printStackTrace(); | ||||
|                     } | ||||
|                 }).start(); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean onOptionsItemSelected(MenuItem item) { | ||||
|         if (item.getItemId() == android.R.id.home) { | ||||
|             finish(); | ||||
|             return true; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void get(Status status) { | ||||
|         firstMessage = status; | ||||
|         invalidateOptionsMenu(); | ||||
|     } | ||||
| } | ||||
|  | @ -47,6 +47,7 @@ import app.fedilab.android.R; | |||
| import app.fedilab.android.databinding.DrawerConversationBinding; | ||||
| import app.fedilab.android.databinding.ThumbnailBinding; | ||||
| import app.fedilab.android.mastodon.activities.ContextActivity; | ||||
| import app.fedilab.android.mastodon.activities.DirectMessageActivity; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Account; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Attachment; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Conversation; | ||||
|  | @ -210,15 +211,26 @@ public class ConversationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH | |||
|         //--- DATE --- | ||||
|         holder.binding.lastMessageDate.setText(Helper.dateDiff(context, conversation.last_status.created_at)); | ||||
| 
 | ||||
|         boolean chatMode = sharedpreferences.getBoolean(context.getString(R.string.SET_CHAT_FOR_CONVERSATION), true); | ||||
|         holder.binding.statusContent.setOnClickListener(v -> { | ||||
|             Intent intent = new Intent(context, ContextActivity.class); | ||||
|             Intent intent; | ||||
|             if (chatMode) { | ||||
|                 intent = new Intent(context, DirectMessageActivity.class); | ||||
|             } else { | ||||
|                 intent = new Intent(context, ContextActivity.class); | ||||
|             } | ||||
|             intent.putExtra(Helper.ARG_STATUS, conversation.last_status); | ||||
|             context.startActivity(intent); | ||||
|         }); | ||||
| 
 | ||||
|         holder.binding.attachmentsListContainer.setOnTouchListener((v, event) -> { | ||||
|             if (event.getAction() == MotionEvent.ACTION_UP) { | ||||
|                 Intent intent = new Intent(context, ContextActivity.class); | ||||
|                 Intent intent; | ||||
|                 if (chatMode) { | ||||
|                     intent = new Intent(context, DirectMessageActivity.class); | ||||
|                 } else { | ||||
|                     intent = new Intent(context, ContextActivity.class); | ||||
|                 } | ||||
|                 intent.putExtra(Helper.ARG_STATUS, conversation.last_status); | ||||
|                 context.startActivity(intent); | ||||
|             } | ||||
|  |  | |||
|  | @ -0,0 +1,106 @@ | |||
| package app.fedilab.android.mastodon.ui.drawer; | ||||
| /* Copyright 2023 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.content.Context; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.ViewGroup; | ||||
| import android.widget.TextView; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.recyclerview.widget.RecyclerView; | ||||
| 
 | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| 
 | ||||
| import java.lang.ref.WeakReference; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import app.fedilab.android.R; | ||||
| import app.fedilab.android.activities.MainActivity; | ||||
| import app.fedilab.android.databinding.DrawerStatusChatBinding; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Status; | ||||
| import app.fedilab.android.mastodon.helper.Helper; | ||||
| import app.fedilab.android.mastodon.helper.MastodonHelper; | ||||
| import app.fedilab.android.mastodon.helper.ThemeHelper; | ||||
| 
 | ||||
| public class StatusDirectMessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { | ||||
| 
 | ||||
|     private final List<Status> statusList; | ||||
|     private Context context; | ||||
|     private RecyclerView mRecyclerView; | ||||
| 
 | ||||
|     public StatusDirectMessageAdapter(List<Status> data) { | ||||
|         this.statusList = data; | ||||
|     } | ||||
| 
 | ||||
|     @NotNull | ||||
|     @Override | ||||
|     public RecyclerView.ViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) { | ||||
|         context = parent.getContext(); | ||||
|         DrawerStatusChatBinding itemBinding = DrawerStatusChatBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); | ||||
|         return new StatusChatViewHolder(itemBinding); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { | ||||
| 
 | ||||
|         StatusChatViewHolder holder = (StatusChatViewHolder) viewHolder; | ||||
|         Status status = statusList.get(position); | ||||
| 
 | ||||
|         holder.binding.messageContent.setText( | ||||
|                 status.getSpanContent(context, | ||||
|                         new WeakReference<>(holder.binding.messageContent), | ||||
|                         () -> mRecyclerView.post(() -> notifyItemChanged(holder.getBindingAdapterPosition()))), | ||||
|                 TextView.BufferType.SPANNABLE); | ||||
| 
 | ||||
|         MastodonHelper.loadPPMastodon(holder.binding.userPp, status.account); | ||||
|         holder.binding.date.setText(Helper.longDateToString(status.created_at)); | ||||
|         //Owner account | ||||
|         int textColor; | ||||
|         if (status.account.id.equals(MainActivity.currentUserID)) { | ||||
|             holder.binding.mainContainer.setBackgroundResource(R.drawable.bubble_right_tail); | ||||
|             textColor = R.attr.colorOnPrimary; | ||||
|         } else { | ||||
|             holder.binding.mainContainer.setBackgroundResource(R.drawable.bubble_left_tail); | ||||
|             textColor = R.attr.colorOnSecondary; | ||||
|         } | ||||
|         holder.binding.date.setTextColor(ThemeHelper.getAttColor(context, textColor)); | ||||
|         holder.binding.messageContent.setTextColor(ThemeHelper.getAttColor(context, textColor)); | ||||
|         holder.binding.userName.setTextColor(ThemeHelper.getAttColor(context, textColor)); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { | ||||
|         super.onAttachedToRecyclerView(recyclerView); | ||||
| 
 | ||||
|         mRecyclerView = recyclerView; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public int getItemCount() { | ||||
|         return statusList.size(); | ||||
|     } | ||||
| 
 | ||||
|     public static class StatusChatViewHolder extends RecyclerView.ViewHolder { | ||||
|         DrawerStatusChatBinding binding; | ||||
| 
 | ||||
|         StatusChatViewHolder(DrawerStatusChatBinding itemView) { | ||||
|             super(itemView.getRoot()); | ||||
|             binding = itemView; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,143 @@ | |||
| package app.fedilab.android.mastodon.ui.fragment.timeline; | ||||
| /* Copyright 2023 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.os.Bundle; | ||||
| import android.view.LayoutInflater; | ||||
| import android.view.View; | ||||
| import android.view.ViewGroup; | ||||
| 
 | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.lifecycle.ViewModelProvider; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import app.fedilab.android.R; | ||||
| import app.fedilab.android.activities.MainActivity; | ||||
| import app.fedilab.android.databinding.FragmentPaginationBinding; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Context; | ||||
| import app.fedilab.android.mastodon.client.entities.api.Status; | ||||
| import app.fedilab.android.mastodon.helper.Helper; | ||||
| import app.fedilab.android.mastodon.ui.drawer.StatusDirectMessageAdapter; | ||||
| import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM; | ||||
| 
 | ||||
| 
 | ||||
| public class FragmentMastodonDirectMessage extends Fragment { | ||||
| 
 | ||||
| 
 | ||||
|     public FirstMessage firstMessage; | ||||
|     private FragmentPaginationBinding binding; | ||||
|     private StatusesVM statusesVM; | ||||
|     private List<Status> statuses; | ||||
|     private StatusDirectMessageAdapter statusDirectMessageAdapter; | ||||
|     //Handle actions that can be done in other fragments | ||||
|     private Status focusedStatus; | ||||
|     private Status firstStatus; | ||||
|     private boolean pullToRefresh; | ||||
|     private String user_token, user_instance; | ||||
| 
 | ||||
| 
 | ||||
|     public View onCreateView(@NonNull LayoutInflater inflater, | ||||
|                              ViewGroup container, Bundle savedInstanceState) { | ||||
| 
 | ||||
|         focusedStatus = null; | ||||
|         pullToRefresh = false; | ||||
|         if (getArguments() != null) { | ||||
|             focusedStatus = (Status) getArguments().getSerializable(Helper.ARG_STATUS); | ||||
|         } | ||||
|         user_instance = MainActivity.currentInstance; | ||||
|         user_token = MainActivity.currentToken; | ||||
| 
 | ||||
|         if (focusedStatus == null) { | ||||
|             getChildFragmentManager().beginTransaction().remove(this).commit(); | ||||
|         } | ||||
|         binding = FragmentPaginationBinding.inflate(inflater, container, false); | ||||
|         statusesVM = new ViewModelProvider(FragmentMastodonDirectMessage.this).get(StatusesVM.class); | ||||
|         binding.recyclerView.setNestedScrollingEnabled(true); | ||||
|         this.statuses = new ArrayList<>(); | ||||
|         this.statuses.add(focusedStatus); | ||||
|         statusDirectMessageAdapter = new StatusDirectMessageAdapter(this.statuses); | ||||
|         binding.swipeContainer.setRefreshing(false); | ||||
|         LinearLayoutManager mLayoutManager = new LinearLayoutManager(requireActivity()); | ||||
|         binding.recyclerView.setLayoutManager(mLayoutManager); | ||||
|         binding.recyclerView.setAdapter(statusDirectMessageAdapter); | ||||
|         binding.swipeContainer.setOnRefreshListener(() -> { | ||||
|             if (this.statuses.size() > 0) { | ||||
|                 binding.swipeContainer.setRefreshing(true); | ||||
|                 pullToRefresh = true; | ||||
|                 statusesVM.getContext(user_instance, user_token, focusedStatus.id) | ||||
|                         .observe(getViewLifecycleOwner(), this::initializeContextView); | ||||
|             } | ||||
|         }); | ||||
|         if (focusedStatus != null) { | ||||
|             statusesVM.getContext(user_instance, user_token, focusedStatus.id) | ||||
|                     .observe(getViewLifecycleOwner(), this::initializeContextView); | ||||
|         } | ||||
|         return binding.getRoot(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * Intialize the common view for the context | ||||
|      * | ||||
|      * @param context {@link Context} | ||||
|      */ | ||||
|     private void initializeContextView(final Context context) { | ||||
| 
 | ||||
|         if (context == null) { | ||||
|             Helper.sendToastMessage(requireActivity(), Helper.RECEIVE_TOAST_TYPE_ERROR, getString(R.string.toast_error)); | ||||
|             return; | ||||
|         } | ||||
|         if (binding == null || !isAdded() || getActivity() == null) { | ||||
|             return; | ||||
|         } | ||||
|         if (pullToRefresh) { | ||||
|             pullToRefresh = false; | ||||
|             int size = this.statuses.size(); | ||||
|             statuses.clear(); | ||||
|             statusDirectMessageAdapter.notifyItemRangeRemoved(0, size); | ||||
|             statuses.add(focusedStatus); | ||||
|         } | ||||
|         if (context.ancestors.size() > 0) { | ||||
|             firstStatus = context.ancestors.get(0); | ||||
|         } else { | ||||
|             firstStatus = statuses.get(0); | ||||
|         } | ||||
|         if (firstMessage != null) { | ||||
|             firstMessage.get(firstStatus); | ||||
|         } | ||||
| 
 | ||||
|         int statusPosition = context.ancestors.size(); | ||||
|         //Build the array of statuses | ||||
|         statuses.addAll(0, context.ancestors); | ||||
|         statusDirectMessageAdapter.notifyItemRangeInserted(0, statusPosition); | ||||
|         statuses.addAll(statusPosition + 1, context.descendants); | ||||
|         statusDirectMessageAdapter.notifyItemRangeInserted(statusPosition + 1, context.descendants.size()); | ||||
|         if (binding.recyclerView.getItemDecorationCount() > 0) { | ||||
|             for (int i = 0; i < binding.recyclerView.getItemDecorationCount(); i++) { | ||||
|                 binding.recyclerView.removeItemDecorationAt(i); | ||||
|             } | ||||
|         } | ||||
|         binding.swipeContainer.setRefreshing(false); | ||||
|         binding.recyclerView.scrollToPosition(statusPosition); | ||||
|     } | ||||
| 
 | ||||
|     public interface FirstMessage { | ||||
|         void get(Status status); | ||||
|     } | ||||
| } | ||||
|  | @ -1,12 +0,0 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
| 
 | ||||
|     <item | ||||
|         android:drawable="@drawable/ic_block_script" | ||||
|         android:gravity="center" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/ic_block_count" | ||||
|         android:drawable="@color/transparent" /> | ||||
| 
 | ||||
| </layer-list> | ||||
|  | @ -1,4 +1,3 @@ | |||
| <?xml version="1.0" encoding="utf-8"?><?xml version="1.0" encoding="utf-8"?> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:left="5dp"> | ||||
|         <shape> | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:right="20dp"> | ||||
|         <rotate | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| <?xml version="1.0" encoding="utf-8"?><?xml version="1.0" encoding="utf-8"?> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:right="5dp"> | ||||
|         <shape> | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||||
|     <item android:left="20dp"> | ||||
|         <rotate | ||||
|  |  | |||
|  | @ -0,0 +1,70 @@ | |||
| <?xml version="1.0" encoding="utf-8"?><!-- | ||||
|     Copyright 2023 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> | ||||
| --> | ||||
| <androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:id="@+id/drawer_layout" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent" | ||||
|     android:fitsSystemWindows="true" | ||||
|     tools:openDrawer="start"> | ||||
| 
 | ||||
|     <androidx.coordinatorlayout.widget.CoordinatorLayout | ||||
|         android:layout_width="match_parent" | ||||
|         android:layout_height="match_parent" | ||||
|         tools:context=".mastodon.activities.ContextActivity"> | ||||
| 
 | ||||
|         <com.google.android.material.appbar.AppBarLayout | ||||
|             android:id="@+id/appBar" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="wrap_content"> | ||||
| 
 | ||||
|             <androidx.appcompat.widget.Toolbar | ||||
|                 android:id="@+id/toolbar" | ||||
|                 android:layout_width="match_parent" | ||||
|                 android:layout_height="?attr/actionBarSize" | ||||
|                 android:fitsSystemWindows="true" | ||||
|                 app:layout_scrollFlags="scroll|enterAlways"> | ||||
| 
 | ||||
|                 <ImageView | ||||
|                     android:id="@+id/profile_picture" | ||||
|                     android:layout_width="30dp" | ||||
|                     android:layout_height="30dp" | ||||
|                     android:layout_marginEnd="10dp" | ||||
|                     android:contentDescription="@string/profile_picture" /> | ||||
| 
 | ||||
|                 <androidx.appcompat.widget.AppCompatTextView | ||||
|                     android:id="@+id/title" | ||||
|                     style="@style/TextAppearance.AppCompat.Title" | ||||
|                     android:layout_width="wrap_content" | ||||
|                     android:layout_height="wrap_content" | ||||
|                     android:layout_gravity="center_vertical" | ||||
|                     android:ellipsize="end" | ||||
|                     android:maxLines="1" /> | ||||
|             </androidx.appcompat.widget.Toolbar> | ||||
| 
 | ||||
|         </com.google.android.material.appbar.AppBarLayout> | ||||
| 
 | ||||
|         <androidx.fragment.app.FragmentContainerView | ||||
|             android:id="@+id/nav_host_fragment_content_main" | ||||
|             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" /> | ||||
|     </androidx.coordinatorlayout.widget.CoordinatorLayout> | ||||
| </androidx.drawerlayout.widget.DrawerLayout> | ||||
|  | @ -2,6 +2,7 @@ | |||
| <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     android:id="@+id/mainContainer" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="wrap_content" | ||||
|     android:layout_marginHorizontal="@dimen/fab_margin" | ||||
|  |  | |||
|  | @ -1,5 +0,0 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <resources> | ||||
| 
 | ||||
| 
 | ||||
| </resources> | ||||
|  | @ -1,11 +1,6 @@ | |||
| <?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_block" | ||||
|         android:icon="@drawable/browser_calls_blocked" | ||||
|         android:title="@string/calls_blocked" | ||||
|         app:showAsAction="always" /> | ||||
|     <item | ||||
|         android:id="@+id/action_go" | ||||
|         android:icon="@drawable/ic_baseline_open_with_24" | ||||
|  |  | |||
|  | @ -1029,6 +1029,8 @@ | |||
|     <string name="SET_DYNAMICCOLOR" translatable="false">SET_DYNAMICCOLOR</string> | ||||
|     <string name="SET_CARDVIEW" translatable="false">SET_CARDVIEW</string> | ||||
|     <string name="SET_CUSTOMIZE_LIGHT_COLORS" translatable="false">SET_CUSTOMIZE_LIGHT_COLORS</string> | ||||
|     <string name="SET_CHAT_FOR_CONVERSATION" translatable="false">SET_CHAT_FOR_CONVERSATION</string> | ||||
| 
 | ||||
|     <string name="SET_CUSTOMIZE_LIGHT_COLORS_ACTION" translatable="false">SET_CUSTOMIZE_LIGHT_COLORS_ACTION</string> | ||||
|     <string name="SET_CUSTOMIZE_DARK_COLORS" translatable="false">SET_CUSTOMIZE_DARK_COLORS</string> | ||||
|     <string name="SET_CUSTOMIZE_DARK_COLORS_ACTION" translatable="false">SET_CUSTOMIZE_DARK_COLORS_ACTION</string> | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue