mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2024-12-22 16:50:04 +02:00
Message history
This commit is contained in:
parent
0189dad4d3
commit
13a1a2a7a4
10 changed files with 399 additions and 0 deletions
|
@ -156,6 +156,11 @@
|
|||
<activity
|
||||
android:name=".activities.WebviewConnectActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
<activity
|
||||
android:name=".activities.StatusHistoryActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize"
|
||||
android:label="@string/status_history"
|
||||
android:theme="@style/AppThemeBar" />
|
||||
<activity
|
||||
android:name=".activities.ContextActivity"
|
||||
android:configChanges="keyboardHidden|orientation|screenSize" />
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
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.content.res.Resources;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.databinding.ActivityStatusHistoryBinding;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.ThemeHelper;
|
||||
import app.fedilab.android.ui.drawer.StatusHistoryAdapter;
|
||||
import app.fedilab.android.viewmodel.mastodon.StatusesVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
||||
public class StatusHistoryActivity extends BaseActivity {
|
||||
|
||||
public static Resources.Theme theme;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeHelper.applyTheme(this);
|
||||
ActivityStatusHistoryBinding binding = ActivityStatusHistoryBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.cyanea_primary)));
|
||||
}
|
||||
|
||||
Bundle b = getIntent().getExtras();
|
||||
String statusId;
|
||||
if (b != null) {
|
||||
statusId = b.getString(Helper.ARG_STATUS_ID);
|
||||
} else {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
StatusesVM statusesVM = new ViewModelProvider(StatusHistoryActivity.this).get(StatusesVM.class);
|
||||
statusesVM.getStatusHistory(MainActivity.currentInstance, MainActivity.currentToken, statusId).observe(this, statuses -> {
|
||||
if (statuses != null && statuses.size() > 0) {
|
||||
StatusHistoryAdapter statusHistoryAdapter = new StatusHistoryAdapter(statuses);
|
||||
binding.recyclerView.setAdapter(statusHistoryAdapter);
|
||||
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
} else {
|
||||
Toasty.error(this, getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -67,6 +67,11 @@ public interface MastodonStatusesService {
|
|||
@Header("Authorization") String token,
|
||||
@Path("id") String id);
|
||||
|
||||
@GET("statuses/{id}/history")
|
||||
Call<List<Status>> getStatusHistory(
|
||||
@Header("Authorization") String token,
|
||||
@Path("id") String id);
|
||||
|
||||
//Post a status
|
||||
@FormUrlEncoded
|
||||
@PUT("statuses/{id}")
|
||||
|
|
|
@ -378,6 +378,8 @@ public class Timeline {
|
|||
TREND_TAG("TREND_TAG"),
|
||||
@SerializedName("TREND_MESSAGE")
|
||||
TREND_MESSAGE("TREND_MESSAGE"),
|
||||
@SerializedName("STATUS_HISTORY")
|
||||
STATUS_HISTORY("STATUS_HISTORY"),
|
||||
@SerializedName("ACCOUNT_TIMELINE")
|
||||
ACCOUNT_TIMELINE("ACCOUNT_TIMELINE"),
|
||||
@SerializedName("MUTED_TIMELINE")
|
||||
|
|
|
@ -104,6 +104,7 @@ import app.fedilab.android.activities.MainActivity;
|
|||
import app.fedilab.android.activities.MediaActivity;
|
||||
import app.fedilab.android.activities.ProfileActivity;
|
||||
import app.fedilab.android.activities.ReportActivity;
|
||||
import app.fedilab.android.activities.StatusHistoryActivity;
|
||||
import app.fedilab.android.activities.StatusInfoActivity;
|
||||
import app.fedilab.android.client.entities.api.Attachment;
|
||||
import app.fedilab.android.client.entities.api.Poll;
|
||||
|
@ -983,6 +984,11 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
|
||||
if (statusToDeal.edited_at != null) {
|
||||
holder.binding.time.setText(context.getString(R.string.full_date_edited, Helper.longDateToString(status.created_at), Helper.longDateToString(status.edited_at)));
|
||||
holder.binding.time.setOnClickListener(v -> {
|
||||
Intent historyIntent = new Intent(context, StatusHistoryActivity.class);
|
||||
historyIntent.putExtra(Helper.ARG_STATUS_ID, statusToDeal.id);
|
||||
context.startActivity(historyIntent);
|
||||
});
|
||||
} else {
|
||||
holder.binding.time.setText(Helper.longDateToString(status.created_at));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
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.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.client.entities.api.Status;
|
||||
import app.fedilab.android.databinding.DrawerStatusHistoryBinding;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.MastodonHelper;
|
||||
|
||||
|
||||
public class StatusHistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
|
||||
private final List<Status> statuses;
|
||||
private Context context;
|
||||
|
||||
public StatusHistoryAdapter(List<Status> statusList) {
|
||||
statuses = statusList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
context = parent.getContext();
|
||||
DrawerStatusHistoryBinding itemBinding = DrawerStatusHistoryBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new StatusHistoryViewHolder(itemBinding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||
StatusHistoryViewHolder holder = (StatusHistoryViewHolder) viewHolder;
|
||||
Status status = statuses.get(position);
|
||||
holder.binding.statusContent.setText(
|
||||
status.getSpanContent(context,
|
||||
new WeakReference<>(holder.binding.statusContent)),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
if (status.spoiler_text != null && !status.spoiler_text.trim().isEmpty()) {
|
||||
holder.binding.spoiler.setVisibility(View.VISIBLE);
|
||||
holder.binding.spoiler.setText(
|
||||
status.getSpanSpoiler(context,
|
||||
new WeakReference<>(holder.binding.spoiler)),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
} else {
|
||||
holder.binding.spoiler.setVisibility(View.GONE);
|
||||
holder.binding.spoiler.setText(null);
|
||||
}
|
||||
MastodonHelper.loadPPMastodon(holder.binding.avatar, status.account);
|
||||
if (status.account != null) {
|
||||
holder.binding.displayName.setText(
|
||||
status.account.getSpanDisplayName(context,
|
||||
new WeakReference<>(holder.binding.displayName)),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
holder.binding.username.setText(String.format("@%s", status.account.acct));
|
||||
}
|
||||
int theme_statuses_color = -1;
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (sharedpreferences.getBoolean("use_custom_theme", false)) {
|
||||
theme_statuses_color = sharedpreferences.getInt("theme_statuses_color", -1);
|
||||
}
|
||||
if (theme_statuses_color != -1) {
|
||||
holder.binding.cardviewContainer.setBackgroundColor(theme_statuses_color);
|
||||
} else {
|
||||
holder.binding.cardviewContainer.setBackgroundColor(ContextCompat.getColor(context, R.color.cyanea_primary_dark_reference));
|
||||
}
|
||||
if (position == 0) {
|
||||
holder.binding.dateModif.setText(context.getString(R.string.created_message_at, Helper.dateDiffFull(status.created_at)));
|
||||
} else {
|
||||
holder.binding.dateModif.setText(context.getString(R.string.edited_message_at, Helper.dateDiffFull(status.created_at)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return statuses.size();
|
||||
}
|
||||
|
||||
public static class StatusHistoryViewHolder extends RecyclerView.ViewHolder {
|
||||
DrawerStatusHistoryBinding binding;
|
||||
|
||||
StatusHistoryViewHolder(DrawerStatusHistoryBinding itemView) {
|
||||
super(itemView.getRoot());
|
||||
binding = itemView;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,6 +64,7 @@ public class StatusesVM extends AndroidViewModel {
|
|||
|
||||
|
||||
private MutableLiveData<Status> statusMutableLiveData;
|
||||
private MutableLiveData<List<Status>> statusListMutableLiveData;
|
||||
private MutableLiveData<StatusSource> statusSourceMutableLiveData;
|
||||
private MutableLiveData<ScheduledStatus> scheduledStatusMutableLiveData;
|
||||
private MutableLiveData<ScheduledStatuses> scheduledStatusesMutableLiveData;
|
||||
|
@ -333,6 +334,38 @@ public class StatusesVM extends AndroidViewModel {
|
|||
return statusSourceMutableLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a history of statuses by id
|
||||
*
|
||||
* @param instance Instance domain of the active account
|
||||
* @param token Access token of the active account
|
||||
* @param id String - id of the status
|
||||
* @return LiveData<Status>
|
||||
*/
|
||||
public LiveData<List<Status>> getStatusHistory(@NonNull String instance, String token, String id) {
|
||||
MastodonStatusesService mastodonStatusesService = init(instance);
|
||||
statusListMutableLiveData = new MutableLiveData<>();
|
||||
new Thread(() -> {
|
||||
Call<List<Status>> statusListCall = mastodonStatusesService.getStatusHistory(token, id);
|
||||
List<Status> statusList = null;
|
||||
if (statusListCall != null) {
|
||||
try {
|
||||
Response<List<Status>> statusResponse = statusListCall.execute();
|
||||
if (statusResponse.isSuccessful()) {
|
||||
statusList = statusResponse.body();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
List<Status> finalStatusList = statusList;
|
||||
Runnable myRunnable = () -> statusListMutableLiveData.setValue(finalStatusList);
|
||||
mainHandler.post(myRunnable);
|
||||
}).start();
|
||||
return statusListMutableLiveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a status by ID
|
||||
*
|
||||
|
|
45
app/src/main/res/layout/activity_status_history.xml
Normal file
45
app/src/main/res/layout/activity_status_history.xml
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?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>.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<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" />
|
||||
|
||||
<!-- Main Loader -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/loader"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:visibility="gone">
|
||||
|
||||
<ProgressBar
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
android:indeterminateTint="@color/cyanea_accent_dark_reference" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
103
app/src/main/res/layout/drawer_status_history.xml
Normal file
103
app/src/main/res/layout/drawer_status_history.xml
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2021 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>
|
||||
-->
|
||||
<com.google.android.material.card.MaterialCardView 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/cardview_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/status_user_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal"
|
||||
android:padding="6dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:scaleType="centerInside"
|
||||
tools:src="@drawable/ic_person" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/display_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
tools:text="Display Name" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/username"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:alpha="0.7"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
tools:text="\@username\@instance.test" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/date_modif"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
tools:text="@tools:sample/date/ddmmyy" />
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp" />
|
||||
|
||||
<app.fedilab.android.helper.CustomTextView
|
||||
android:id="@+id/spoiler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
tools:text="Warning: Lorem Ipsum below" />
|
||||
|
||||
<app.fedilab.android.helper.CustomTextView
|
||||
android:id="@+id/status_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:textIsSelectable="true"
|
||||
tools:maxLines="10"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -1557,4 +1557,7 @@
|
|||
<string name="set_live_translate">Force translation to a specific language. Choose first value to reset to device settings</string>
|
||||
<string name="edit_message">Edit message</string>
|
||||
<string name="full_date_edited">%1$s edited %2$s</string>
|
||||
<string name="status_history">Message history</string>
|
||||
<string name="edited_message_at">Edited at %1$s</string>
|
||||
<string name="created_message_at">Created at %1$s</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue