diff --git a/app/build.gradle b/app/build.gradle
index 064abf9c..9a77c3f9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,8 +12,8 @@ android {
applicationId 'org.nuclearfog.twidda'
minSdkVersion 21
targetSdkVersion 34
- versionCode 100
- versionName '3.4.4'
+ versionCode 101
+ versionName '3.4.5'
resConfigs 'en', 'es', 'de-rDE', 'zh-rCN'
}
@@ -48,7 +48,7 @@ android {
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
- implementation 'androidx.recyclerview:recyclerview:1.3.1'
+ implementation 'androidx.recyclerview:recyclerview:1.3.2'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 05b23e58..9749555e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -130,6 +130,11 @@
android:screenOrientation="portrait"
android:theme="@style/AppTheme" />
+
+
());
ResponseBody body = response.body();
if (response.code() == 200 && body != null) {
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/EditedMastodonStatus.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/EditedMastodonStatus.java
index f6fc32f5..273d8eda 100644
--- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/EditedMastodonStatus.java
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/EditedMastodonStatus.java
@@ -8,6 +8,7 @@ import org.json.JSONObject;
import org.nuclearfog.twidda.backend.utils.StringUtils;
import org.nuclearfog.twidda.model.EditedStatus;
import org.nuclearfog.twidda.model.Emoji;
+import org.nuclearfog.twidda.model.Location;
import org.nuclearfog.twidda.model.Media;
import org.nuclearfog.twidda.model.Poll;
import org.nuclearfog.twidda.model.User;
@@ -38,9 +39,8 @@ public class EditedMastodonStatus implements EditedStatus {
JSONArray mediaArray = json.optJSONArray("media_attachments");
JSONArray emojiArray = json.optJSONArray("emojis");
String content = json.optString("content", "");
- String spoilerText = json.optString("spoiler_text", "");
text = StringUtils.extractText(content);
- spoiler = !content.equals(spoilerText);
+ spoiler = json.optBoolean("spoiler_text", false);
sensitive = json.optBoolean("sensitive", false);
timestamp = StringUtils.getIsoTime(json.optString("created_at"));
author = new MastodonUser(json.getJSONObject("account"), currentUserId);
@@ -112,4 +112,11 @@ public class EditedMastodonStatus implements EditedStatus {
public Emoji[] getEmojis() {
return emojis;
}
+
+
+ @Nullable
+ @Override
+ public Location getLocation() {
+ return null;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/async/EditHistoryLoader.java b/app/src/main/java/org/nuclearfog/twidda/backend/async/EditHistoryLoader.java
new file mode 100644
index 00000000..aa437dc1
--- /dev/null
+++ b/app/src/main/java/org/nuclearfog/twidda/backend/async/EditHistoryLoader.java
@@ -0,0 +1,55 @@
+package org.nuclearfog.twidda.backend.async;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.nuclearfog.twidda.backend.api.Connection;
+import org.nuclearfog.twidda.backend.api.ConnectionException;
+import org.nuclearfog.twidda.backend.api.ConnectionManager;
+import org.nuclearfog.twidda.model.lists.StatusEditHistory;
+
+/**
+ * Async loader for {@link org.nuclearfog.twidda.ui.fragments.EditHistoryFragment}
+ *
+ * @author nuclearfog
+ */
+public class EditHistoryLoader extends AsyncExecutor {
+
+ private Connection connection;
+
+ /**
+ *
+ */
+ public EditHistoryLoader(Context context) {
+ connection = ConnectionManager.getDefaultConnection(context);
+ }
+
+
+ @Override
+ protected Result doInBackground(@NonNull Long param) {
+ try {
+ StatusEditHistory history = connection.getStatusEditHistory(param);
+ return new Result(history, null);
+ } catch (ConnectionException exception) {
+ return new Result(null, exception);
+ }
+ }
+
+ /**
+ *
+ */
+ public static class Result {
+
+ @Nullable
+ public final StatusEditHistory history;
+ @Nullable
+ public final ConnectionException exception;
+
+ Result(@Nullable StatusEditHistory history, @Nullable ConnectionException exception) {
+ this.history = history;
+ this.exception = exception;
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/EditedStatus.java b/app/src/main/java/org/nuclearfog/twidda/model/EditedStatus.java
index f0502360..16c655ce 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/EditedStatus.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/EditedStatus.java
@@ -9,7 +9,7 @@ import java.io.Serializable;
*
* @author nuclearfog
*/
-public interface EditedStatus extends Serializable {
+public interface EditedStatus extends Serializable, Comparable {
/**
* @return timestamp of this revision
@@ -51,4 +51,18 @@ public interface EditedStatus extends Serializable {
* @return array of emojis used in the text
*/
Emoji[] getEmojis();
+
+ /**
+ * @return location associated with this status
+ */
+ @Nullable
+ Location getLocation();
+
+ /**
+ *
+ */
+ @Override
+ default int compareTo(EditedStatus status) {
+ return Long.compare(status.getTimestamp(), getTimestamp());
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/ScheduledStatus.java b/app/src/main/java/org/nuclearfog/twidda/model/ScheduledStatus.java
index 43e1007e..bee96d69 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/ScheduledStatus.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/ScheduledStatus.java
@@ -9,7 +9,7 @@ import java.io.Serializable;
*
* @author nuclearfog
*/
-public interface ScheduledStatus extends Serializable {
+public interface ScheduledStatus extends Serializable, Comparable {
/**
* @return ID of the scheduled status
@@ -56,4 +56,11 @@ public interface ScheduledStatus extends Serializable {
* @return true if status contains spoiler information
*/
boolean isSpoiler();
+
+ /**
+ *
+ */
+ default int compareTo(ScheduledStatus status) {
+ return Long.compare(status.getId(), getId());
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Accounts.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Accounts.java
index ee6ac2f8..f2022cbb 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Accounts.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Accounts.java
@@ -1,5 +1,7 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
+
import org.nuclearfog.twidda.model.Account;
import java.util.LinkedList;
@@ -24,4 +26,11 @@ public class Accounts extends LinkedList {
public Accounts(Accounts accounts) {
super(accounts);
}
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "item_count=" + size();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Domains.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Domains.java
index a1c79004..eaea1cc9 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Domains.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Domains.java
@@ -1,5 +1,7 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
+
import java.util.LinkedList;
/**
@@ -69,12 +71,35 @@ public class Domains extends LinkedList {
super.addAll(index, list);
}
+
/**
- * get cursor for next items
+ * get previous cursor of this list
+ *
+ * @return cursor or 0L if not set
+ */
+ public long getPreviousCursor() {
+ return prevCursor;
+ }
+
+ /**
+ * get next cursor of this list
*
* @return cursor or 0L if not set
*/
public long getNextCursor() {
return nextCursor;
}
+
+
+ @Override
+ @NonNull
+ public String toString() {
+ int itemCount = 0;
+ for (String item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount + " previous=" + getPreviousCursor() + " next=" + getNextCursor();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java
index 63b66158..08efdb57 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Fields.java
@@ -33,6 +33,6 @@ public class Fields extends LinkedList {
@NonNull
@Override
public String toString() {
- return "size=" + size();
+ return "item_count=" + size();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Filters.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Filters.java
index d61c2088..164e6799 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Filters.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Filters.java
@@ -1,5 +1,7 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
+
import org.nuclearfog.twidda.model.Filter;
import java.util.LinkedList;
@@ -15,4 +17,11 @@ public class Filters extends LinkedList {
public Filters() {
super();
}
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "item_count=" + size();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Hashtags.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Hashtags.java
index 4c568226..87eacfd9 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Hashtags.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Hashtags.java
@@ -101,6 +101,12 @@ public class Hashtags extends LinkedList {
@Override
@NonNull
public String toString() {
- return "size=" + size() + " min_id=" + prevCursor + " max_id=" + nextCursor;
+ int itemCount = 0;
+ for (Hashtag item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount + " previous=" + getPreviousCursor() + " next=" + getNextCursor();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Notifications.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Notifications.java
index a16250a8..75981dac 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Notifications.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Notifications.java
@@ -1,5 +1,7 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
+
import org.nuclearfog.twidda.model.Notification;
import java.util.LinkedList;
@@ -24,4 +26,17 @@ public class Notifications extends LinkedList {
public Notifications(Notifications notifications) {
super(notifications);
}
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ int itemCount = 0;
+ for (Notification item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Rules.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Rules.java
index 60025035..cd50be8f 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Rules.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Rules.java
@@ -1,5 +1,7 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
+
import org.nuclearfog.twidda.model.Rule;
import java.util.ArrayList;
@@ -23,4 +25,11 @@ public class Rules extends ArrayList {
public Rules(int cap) {
super(cap);
}
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "item_count=" + size();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/ScheduledStatuses.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/ScheduledStatuses.java
index 50dc04f9..f12699b6 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/ScheduledStatuses.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/ScheduledStatuses.java
@@ -1,5 +1,6 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.model.ScheduledStatus;
@@ -28,4 +29,17 @@ public class ScheduledStatuses extends LinkedList {
public ScheduledStatus get(int index) {
return super.get(index);
}
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ int itemCount = 0;
+ for (ScheduledStatus item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/StatusEditHistory.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/StatusEditHistory.java
new file mode 100644
index 00000000..a2b7d4d0
--- /dev/null
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/StatusEditHistory.java
@@ -0,0 +1,35 @@
+package org.nuclearfog.twidda.model.lists;
+
+import androidx.annotation.NonNull;
+
+import org.nuclearfog.twidda.model.EditedStatus;
+
+import java.util.LinkedList;
+
+/**
+ * @author nuclearfog
+ */
+public class StatusEditHistory extends LinkedList {
+
+ private static final long serialVersionUID = 6241896565923670373L;
+
+ /**
+ *
+ */
+ public StatusEditHistory() {
+ }
+
+ /**
+ *
+ */
+ public StatusEditHistory(StatusEditHistory items) {
+ super(items);
+ }
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "item_count=" + size();
+ }
+}
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/StatusEditHistoy.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/StatusEditHistoy.java
deleted file mode 100644
index 90b177df..00000000
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/StatusEditHistoy.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.nuclearfog.twidda.model.lists;
-
-import org.nuclearfog.twidda.model.EditedStatus;
-
-import java.util.LinkedList;
-
-/**
- * @author nuclearfog
- */
-public class StatusEditHistoy extends LinkedList {
-
- private static final long serialVersionUID = 6241896565923670373L;
-}
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Statuses.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Statuses.java
index 892f5b14..b099ebdf 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Statuses.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Statuses.java
@@ -1,5 +1,6 @@
package org.nuclearfog.twidda.model.lists;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.nuclearfog.twidda.model.Status;
@@ -134,4 +135,17 @@ public class Statuses extends LinkedList {
prevCursor = statuses.getPreviousCursor();
nextCursor = statuses.getNextCursor();
}
+
+
+ @NonNull
+ @Override
+ public String toString() {
+ int itemCount = 0;
+ for (Status item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount + " prev=" + getPreviousCursor() + " next=" + getNextCursor();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/UserLists.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/UserLists.java
index 87156da0..5f8827c5 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/UserLists.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/UserLists.java
@@ -52,11 +52,20 @@ public class UserLists extends LinkedList {
}
/**
- * get next link to a list
+ * get previous cursor of this list
*
* @return cursor
*/
- public long getNext() {
+ public long getPreviousCursor() {
+ return prevCursor;
+ }
+
+ /**
+ * get next cursor of this list
+ *
+ * @return cursor
+ */
+ public long getNextCursor() {
return nextCursor;
}
@@ -111,6 +120,12 @@ public class UserLists extends LinkedList {
@Override
@NonNull
public String toString() {
- return "size=" + size() + " previous=" + prevCursor + " next=" + nextCursor;
+ int itemCount = 0;
+ for (UserList item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount + " previous=" + getPreviousCursor() + " next=" + getNextCursor();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/model/lists/Users.java b/app/src/main/java/org/nuclearfog/twidda/model/lists/Users.java
index cb231e91..bd0cfdb3 100644
--- a/app/src/main/java/org/nuclearfog/twidda/model/lists/Users.java
+++ b/app/src/main/java/org/nuclearfog/twidda/model/lists/Users.java
@@ -54,7 +54,16 @@ public class Users extends LinkedList {
}
/**
- * get next link to a list
+ * get previous cursor of this list
+ *
+ * @return cursor
+ */
+ public long getPreviousCursor() {
+ return prevCursor;
+ }
+
+ /**
+ * get next cursor of this list
*
* @return cursor
*/
@@ -96,6 +105,12 @@ public class Users extends LinkedList {
@Override
@NonNull
public String toString() {
- return "size=" + size() + " previous=" + prevCursor + " next=" + nextCursor;
+ int itemCount = 0;
+ for (User item : this) {
+ if (item != null) {
+ itemCount++;
+ }
+ }
+ return "item_count=" + itemCount + " previous=" + getPreviousCursor() + " next=" + getNextCursor();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/EditHistoryActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/EditHistoryActivity.java
new file mode 100644
index 00000000..3de3f055
--- /dev/null
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/EditHistoryActivity.java
@@ -0,0 +1,38 @@
+package org.nuclearfog.twidda.ui.activities;
+
+import android.os.Bundle;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.fragment.app.FragmentTransaction;
+
+import org.nuclearfog.twidda.R;
+import org.nuclearfog.twidda.backend.utils.AppStyles;
+import org.nuclearfog.twidda.ui.fragments.EditHistoryFragment;
+
+/**
+ * @author nuclearfog
+ */
+public class EditHistoryActivity extends AppCompatActivity {
+
+ public static final String KEY_ID = EditHistoryFragment.KEY_ID;
+
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.page_fragment);
+ ViewGroup root = findViewById(R.id.page_fragment_root);
+ Toolbar toolbar = findViewById(R.id.page_fragment_toolbar);
+
+ FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
+ fragmentTransaction.replace(R.id.page_fragment_container, EditHistoryFragment.class, getIntent().getExtras());
+ fragmentTransaction.commit();
+
+ toolbar.setTitle(R.string.toolbar_status_history);
+ setSupportActionBar(toolbar);
+ AppStyles.setTheme(root);
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java
index e1048279..55d3b2c8 100644
--- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusActivity.java
@@ -163,11 +163,12 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
private AudioPlayerDialog audioDialog;
private ReportDialog reportDialog;
- private TextView status_source, created_at, status_text, screen_name, username, location_name, sensitive, visibility, spoiler, spoiler_hint, translate_text;
+ private TextView status_source, created_at, status_text, screen_name, username, edited;
+ private TextView location_name, sensitive, visibility, spoiler, spoiler_hint, translate_text;
private Button reply_button, repost_button, like_button, reply_name, repost_name_button;
private ImageView profile_image;
private Toolbar toolbar;
- private View card_container;
+ private RecyclerView card_list;
@Nullable
private Status status;
@@ -187,7 +188,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
super.onCreate(savedInstanceState);
setContentView(R.layout.page_status);
ViewGroup root = findViewById(R.id.page_status_root);
- RecyclerView card_list = findViewById(R.id.page_status_cards);
+ card_list = findViewById(R.id.page_status_cards);
toolbar = findViewById(R.id.page_status_toolbar);
reply_button = findViewById(R.id.page_status_reply);
repost_button = findViewById(R.id.page_status_repost);
@@ -203,10 +204,11 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
sensitive = findViewById(R.id.page_status_sensitive);
spoiler = findViewById(R.id.page_status_spoiler);
visibility = findViewById(R.id.page_status_visibility);
+ edited = findViewById(R.id.page_status_edited);
repost_name_button = findViewById(R.id.page_status_reposter_reference);
translate_text = findViewById(R.id.page_status_text_translate);
spoiler_hint = findViewById(R.id.page_status_text_sensitive_hint);
- card_container = findViewById(R.id.page_status_cards_container);
+ //card_container = findViewById(R.id.page_status_cards_container);
clip = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
statusLoader = new StatusAction(this);
@@ -229,6 +231,7 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
visibility.setCompoundDrawablesWithIntrinsicBounds(R.drawable.global, 0, 0, 0);
reply_name.setCompoundDrawablesWithIntrinsicBounds(R.drawable.back, 0, 0, 0);
repost_name_button.setCompoundDrawablesWithIntrinsicBounds(R.drawable.repost, 0, 0, 0);
+ edited.setCompoundDrawablesWithIntrinsicBounds(R.drawable.edit, 0, 0, 0);
status_text.setMovementMethod(LinkAndScrollMovement.getInstance());
status_text.setLinkTextColor(settings.getHighlightColor());
card_list.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
@@ -498,7 +501,9 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
}
// get edit history
else if (item.getItemId() == R.id.menu_status_history) {
- // todo implement history viewer
+ Intent intent = new Intent(this, EditHistoryActivity.class);
+ intent.putExtra(EditHistoryActivity.KEY_ID, status.getId());
+ startActivity(intent);
return true;
}
}
@@ -844,6 +849,11 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
} else {
sensitive.setVisibility(View.GONE);
}
+ if (status.editedAt() != 0L) {
+ edited.setVisibility(View.VISIBLE);
+ } else {
+ edited.setVisibility(View.GONE);
+ }
// set status spoiler warning
if (status.isSpoiler()) {
spoiler.setVisibility(View.VISIBLE);
@@ -895,11 +905,11 @@ public class StatusActivity extends AppCompatActivity implements OnClickListener
}
// set status attachment preview
if ((status.getCards().length > 0 || status.getMedia().length > 0) || status.getPoll() != null) {
- card_container.setVisibility(View.VISIBLE);
+ card_list.setVisibility(View.VISIBLE);
adapter.replaceAll(status, settings.hideSensitiveEnabled());
status_text.setMaxLines(5);
} else {
- card_container.setVisibility(View.GONE);
+ card_list.setVisibility(View.GONE);
status_text.setMaxLines(10);
}
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/EditHistoryAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/EditHistoryAdapter.java
new file mode 100644
index 00000000..be816da2
--- /dev/null
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/EditHistoryAdapter.java
@@ -0,0 +1,62 @@
+package org.nuclearfog.twidda.ui.adapter.recyclerview;
+
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import org.nuclearfog.twidda.model.lists.StatusEditHistory;
+import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.EditHistoryHolder;
+
+/**
+ * RecyclerView adapter for {@link org.nuclearfog.twidda.ui.fragments.EditHistoryFragment}
+ *
+ * @author nuclearfog
+ */
+public class EditHistoryAdapter extends RecyclerView.Adapter {
+
+ private StatusEditHistory items = new StatusEditHistory();
+
+
+ @NonNull
+ @Override
+ public EditHistoryHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new EditHistoryHolder(parent);
+ }
+
+
+ @Override
+ public void onBindViewHolder(@NonNull EditHistoryHolder holder, int position) {
+ holder.setContent(items.get(position));
+ }
+
+
+ @Override
+ public int getItemCount() {
+ return items.size();
+ }
+
+ /**
+ *
+ */
+ public void setItems(StatusEditHistory items) {
+ this.items.clear();
+ this.items.addAll(items);
+ notifyDataSetChanged();
+ }
+
+ /**
+ *
+ */
+ public StatusEditHistory getItems() {
+ return new StatusEditHistory(items);
+ }
+
+ /**
+ *
+ */
+ public void clear() {
+ items.clear();
+ notifyDataSetChanged();
+ }
+}
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/IconAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/IconAdapter.java
index 55616449..dc58cf11 100644
--- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/IconAdapter.java
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/IconAdapter.java
@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView.Adapter;
+import org.nuclearfog.twidda.model.EditedStatus;
import org.nuclearfog.twidda.model.Media;
import org.nuclearfog.twidda.model.Status;
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.IconHolder;
@@ -99,6 +100,23 @@ public class IconAdapter extends Adapter implements OnHolderClickLis
notifyDataSetChanged();
}
+ /**
+ * add icons using edited status information
+ */
+ public void setItems(EditedStatus status) {
+ items.clear();
+ if (status.getMedia().length > 0) {
+ addMediaIcons(status.getMedia());
+ }
+ if (status.getLocation() != null) {
+ items.add(IconHolder.TYPE_LOCATION);
+ }
+ if (status.getPoll() != null) {
+ items.add(IconHolder.TYPE_POLL);
+ }
+ notifyDataSetChanged();
+ }
+
/**
* set media icons
*/
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/UserlistAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/UserlistAdapter.java
index cd54d3f2..9545430a 100644
--- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/UserlistAdapter.java
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/UserlistAdapter.java
@@ -108,7 +108,7 @@ public class UserlistAdapter extends Adapter implements OnHolderClic
@Override
public boolean onPlaceholderClick(int index) {
- boolean actionPerformed = listener.onPlaceholderClick(userlists.getNext(), index);
+ boolean actionPerformed = listener.onPlaceholderClick(userlists.getNextCursor(), index);
if (actionPerformed)
loadingIndex = index;
return actionPerformed;
@@ -133,17 +133,17 @@ public class UserlistAdapter extends Adapter implements OnHolderClic
disableLoading();
if (index < 0) {
userlists.replaceAll(newUserlists);
- if (userlists.getNext() != 0L) {
+ if (userlists.getNextCursor() != 0L) {
// Add placeholder
userlists.add(null);
}
notifyDataSetChanged();
} else {
userlists.addAll(index, newUserlists);
- if (userlists.getNext() != 0L && userlists.peekLast() != null) {
+ if (userlists.getNextCursor() != 0L && userlists.peekLast() != null) {
userlists.add(null);
notifyItemRangeInserted(index, newUserlists.size() + 1);
- } else if (userlists.getNext() == 0L && userlists.peekLast() == null) {
+ } else if (userlists.getNextCursor() == 0L && userlists.peekLast() == null) {
userlists.pollLast();
notifyItemRangeInserted(index, newUserlists.size() - 1);
} else {
@@ -159,7 +159,7 @@ public class UserlistAdapter extends Adapter implements OnHolderClic
*/
public void replaceItems(UserLists newUserlists) {
userlists.replaceAll(newUserlists);
- if (userlists.getNext() != 0L && userlists.peekLast() != null) {
+ if (userlists.getNextCursor() != 0L && userlists.peekLast() != null) {
// Add placeholder
userlists.add(null);
}
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/EditHistoryHolder.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/EditHistoryHolder.java
new file mode 100644
index 00000000..cd3e20b1
--- /dev/null
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/recyclerview/holder/EditHistoryHolder.java
@@ -0,0 +1,191 @@
+package org.nuclearfog.twidda.ui.adapter.recyclerview.holder;
+
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.cardview.widget.CardView;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
+
+import com.squareup.picasso.Picasso;
+import com.squareup.picasso.Transformation;
+
+import org.nuclearfog.tag.Tagger;
+import org.nuclearfog.textviewtool.LinkAndScrollMovement;
+import org.nuclearfog.twidda.R;
+import org.nuclearfog.twidda.backend.async.AsyncExecutor;
+import org.nuclearfog.twidda.backend.async.TextEmojiLoader;
+import org.nuclearfog.twidda.backend.image.PicassoBuilder;
+import org.nuclearfog.twidda.backend.utils.AppStyles;
+import org.nuclearfog.twidda.backend.utils.EmojiUtils;
+import org.nuclearfog.twidda.backend.utils.StringUtils;
+import org.nuclearfog.twidda.config.GlobalSettings;
+import org.nuclearfog.twidda.model.EditedStatus;
+import org.nuclearfog.twidda.model.User;
+import org.nuclearfog.twidda.ui.adapter.recyclerview.IconAdapter;
+
+import java.util.Random;
+
+import jp.wasabeef.picasso.transformations.RoundedCornersTransformation;
+
+/**
+ * View holder for {@link org.nuclearfog.twidda.ui.adapter.recyclerview.EditHistoryAdapter}
+ *
+ * @author nuclearfog
+ */
+public class EditHistoryHolder extends ViewHolder {
+
+ private static final int EMPTY_COLOR = 0x2F000000;
+
+ private static final int IMG_SIZE = 150;
+
+ private static final Random RND = new Random();
+
+ private ImageView profile, icon_lock;
+ private RecyclerView icon_list;
+ private TextView username, screen_name, text, spoiler, sensitive, timestamp;
+
+ private GlobalSettings settings;
+ private Picasso picasso;
+ private TextEmojiLoader emojiLoader;
+ private Drawable placeholder;
+ private IconAdapter adapter;
+
+ private long tagId = RND.nextLong();
+ private AsyncExecutor.AsyncCallback textResult = this::setTextEmojis;
+ private AsyncExecutor.AsyncCallback usernameResult = this::setUsernameEmojis;
+
+ /**
+ *
+ */
+ public EditHistoryHolder(ViewGroup parent) {
+ super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_edit_status, parent, false));
+ settings = GlobalSettings.get(parent.getContext());
+ picasso = PicassoBuilder.get(parent.getContext());
+ placeholder = new ColorDrawable(EMPTY_COLOR);
+ emojiLoader = new TextEmojiLoader(parent.getContext());
+ adapter = new IconAdapter(null, false);
+
+ CardView card = (CardView) itemView;
+ ViewGroup container = itemView.findViewById(R.id.item_edit_status_container);
+ profile = itemView.findViewById(R.id.item_edit_status_profile);
+ username = itemView.findViewById(R.id.item_edit_status_username);
+ screen_name = itemView.findViewById(R.id.item_edit_status_screenname);
+ text = itemView.findViewById(R.id.item_edit_status_text);
+ spoiler = itemView.findViewById(R.id.item_edit_status_spoiler);
+ sensitive = itemView.findViewById(R.id.item_edit_status_sensitive);
+ icon_list = itemView.findViewById(R.id.item_edit_status_attachments);
+ icon_lock = itemView.findViewById(R.id.item_edit_status_locked_icon);
+ timestamp = itemView.findViewById(R.id.item_edit_status_created_at);
+
+ spoiler.setCompoundDrawablesWithIntrinsicBounds(R.drawable.exclamation, 0, 0, 0);
+ sensitive.setCompoundDrawablesWithIntrinsicBounds(R.drawable.sensitive, 0, 0, 0);
+ icon_list.setLayoutManager(new LinearLayoutManager(parent.getContext(), LinearLayoutManager.HORIZONTAL, false));
+ icon_list.setAdapter(adapter);
+ text.setMovementMethod(LinkAndScrollMovement.getInstance());
+ AppStyles.setTheme(container, Color.TRANSPARENT);
+ card.setCardBackgroundColor(settings.getCardColor());
+ }
+
+ /**
+ * set view content
+ *
+ * @param editedStatus edited status content
+ */
+ public void setContent(EditedStatus editedStatus) {
+ User author = editedStatus.getAuthor();
+ // set profile image
+ if (settings.imagesEnabled() && !author.getProfileImageThumbnailUrl().isEmpty()) {
+ Transformation roundCorner = new RoundedCornersTransformation(2, 0);
+ picasso.load(author.getProfileImageThumbnailUrl()).transform(roundCorner).resize(IMG_SIZE, IMG_SIZE)
+ .placeholder(placeholder).centerCrop().error(R.drawable.no_image).into(profile);
+ } else {
+ profile.setImageDrawable(placeholder);
+ }
+ // set status text and emojis
+ if (!editedStatus.getText().trim().isEmpty()) {
+ Spannable textSpan = Tagger.makeTextWithLinks(editedStatus.getText(), settings.getHighlightColor());
+ if (editedStatus.getEmojis().length > 0 && settings.imagesEnabled()) {
+ TextEmojiLoader.Param param = new TextEmojiLoader.Param(tagId, editedStatus.getEmojis(), textSpan, text.getResources().getDimensionPixelSize(R.dimen.item_status_icon_size));
+ emojiLoader.execute(param, textResult);
+ textSpan = EmojiUtils.removeTags(textSpan);
+ }
+ text.setText(textSpan);
+ text.setVisibility(View.VISIBLE);
+ } else {
+ text.setVisibility(View.GONE);
+ }
+ // set username and emojis
+ if (author.getEmojis().length > 0 && !author.getUsername().trim().isEmpty() && settings.imagesEnabled()) {
+ SpannableString usernameSpan = new SpannableString(author.getUsername());
+ TextEmojiLoader.Param param = new TextEmojiLoader.Param(tagId, author.getEmojis(), usernameSpan, username.getResources().getDimensionPixelSize(R.dimen.item_status_icon_size));
+ emojiLoader.execute(param, usernameResult);
+ username.setText(EmojiUtils.removeTags(usernameSpan));
+ } else {
+ username.setText(author.getUsername());
+ }
+ if (author.isProtected()) {
+ icon_lock.setVisibility(View.VISIBLE);
+ } else {
+ icon_lock.setVisibility(View.GONE);
+ }
+ if (editedStatus.isSpoiler()) {
+ spoiler.setVisibility(View.VISIBLE);
+ } else {
+ spoiler.setVisibility(View.GONE);
+ }
+ if (editedStatus.isSensitive()) {
+ sensitive.setVisibility(View.VISIBLE);
+ } else {
+ sensitive.setVisibility(View.GONE);
+ }
+ // setup attachment indicators
+ if (settings.statusIndicatorsEnabled()) {
+ icon_list.setVisibility(View.VISIBLE);
+ adapter.setItems(editedStatus);
+ if (adapter.isEmpty()) {
+ icon_list.setVisibility(View.GONE);
+ } else {
+ icon_list.setVisibility(View.VISIBLE);
+ }
+ } else {
+ icon_list.setVisibility(View.GONE);
+ }
+ screen_name.setText(author.getScreenname());
+ timestamp.setText(StringUtils.formatCreationTime(timestamp.getResources(), editedStatus.getTimestamp()));
+ }
+
+ /**
+ * update username
+ *
+ * @param result username with emojis
+ */
+ private void setUsernameEmojis(@NonNull TextEmojiLoader.Result result) {
+ if (result.id == tagId && result.images != null) {
+ Spannable spannable = EmojiUtils.addEmojis(username.getContext(), result.spannable, result.images);
+ username.setText(spannable);
+ }
+ }
+
+ /**
+ * update status text
+ *
+ * @param result status text with emojis
+ */
+ private void setTextEmojis(@NonNull TextEmojiLoader.Result result) {
+ if (result.id == tagId && result.images != null) {
+ Spannable spannable = EmojiUtils.addEmojis(text.getContext(), result.spannable, result.images);
+ text.setText(spannable);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/fragments/EditHistoryFragment.java b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/EditHistoryFragment.java
new file mode 100644
index 00000000..b3938be4
--- /dev/null
+++ b/app/src/main/java/org/nuclearfog/twidda/ui/fragments/EditHistoryFragment.java
@@ -0,0 +1,90 @@
+package org.nuclearfog.twidda.ui.fragments;
+
+import android.os.Bundle;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback;
+import org.nuclearfog.twidda.backend.async.EditHistoryLoader;
+import org.nuclearfog.twidda.backend.utils.ErrorUtils;
+import org.nuclearfog.twidda.model.lists.StatusEditHistory;
+import org.nuclearfog.twidda.ui.adapter.recyclerview.EditHistoryAdapter;
+
+/**
+ * Status edit history fragment
+ *
+ * @author nuclearfog
+ * @see org.nuclearfog.twidda.ui.activities.EditHistoryActivity
+ */
+public class EditHistoryFragment extends ListFragment implements AsyncCallback {
+
+ public static final String KEY_ID = "status-id";
+
+ private static final String KEY_DATA = "history-save";
+
+ private EditHistoryLoader historyLoader;
+ private EditHistoryAdapter adapter;
+
+ private long id;
+
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ historyLoader = new EditHistoryLoader(requireContext());
+ adapter = new EditHistoryAdapter();
+ setAdapter(adapter);
+
+ if (getArguments() != null) {
+ id = getArguments().getLong(KEY_ID);
+ }
+ if (savedInstanceState != null) {
+ Object data = savedInstanceState.getSerializable(KEY_DATA);
+ if (data instanceof StatusEditHistory) {
+ adapter.setItems((StatusEditHistory) data);
+ }
+ } else {
+ historyLoader.execute(id, this);
+ setRefresh(true);
+ }
+ }
+
+
+ @Override
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ outState.putSerializable(KEY_DATA, adapter.getItems());
+ super.onSaveInstanceState(outState);
+ }
+
+
+ @Override
+ public void onDestroy() {
+ historyLoader.cancel();
+ super.onDestroy();
+ }
+
+
+ @Override
+ protected void onReload() {
+ historyLoader.execute(id, this);
+ }
+
+
+ @Override
+ protected void onReset() {
+ adapter.clear();
+ historyLoader.execute(id, this);
+ }
+
+
+ @Override
+ public void onResult(@NonNull EditHistoryLoader.Result result) {
+ if (result.history != null) {
+ adapter.setItems(result.history);
+ } else {
+ ErrorUtils.showErrorMessage(requireContext(), result.exception);
+ }
+ setRefresh(false);
+ }
+}
diff --git a/app/src/main/res/drawable/edit.xml b/app/src/main/res/drawable/edit.xml
new file mode 100644
index 00000000..0e5050c5
--- /dev/null
+++ b/app/src/main/res/drawable/edit.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/item_edit_status.xml b/app/src/main/res/layout/item_edit_status.xml
new file mode 100644
index 00000000..da1804df
--- /dev/null
+++ b/app/src/main/res/layout/item_edit_status.xml
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/page_status.xml b/app/src/main/res/layout/page_status.xml
index 29ddaa9a..bc151379 100644
--- a/app/src/main/res/layout/page_status.xml
+++ b/app/src/main/res/layout/page_status.xml
@@ -174,39 +174,43 @@
app:layout_constraintStart_toStartOf="@id/page_status_text"
app:layout_constraintTop_toBottomOf="@id/page_status_text" />
-
-
-
-
-
+ app:layout_constraintEnd_toEndOf="parent" />
+ app:layout_constraintTop_toBottomOf="@id/page_status_cards"
+ app:layout_constraintEnd_toStartOf="@id/page_status_edited" />
+
+
+ app:layout_constraintTop_toBottomOf="@id/page_status_cards" />
Liste entfolgen?
\u0020Posts
Verbindung fehlgeschlagen!
+ bearbeitet
Nutzernamen eingeben
Profilbanner
Banner einfügen
@@ -157,6 +158,7 @@
Filter verwalten
Einstellungen
erstelle Nutzerliste
+ Bearbeitungsverlauf
jetzt
folgen
Nutzerlisten
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 18a7b57b..2d540626 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -39,7 +39,7 @@
12sp
18sp
12sp
- 5dp
+ 5dp
130sp
17sp
5
@@ -266,12 +266,22 @@
5dp
13sp
-
+
3dp
24dp
2dp
5dp
+
+ 36sp
+ 5dp
+ 24dp
+ 5dp
+ 5dp
+ 14sp
+ 12sp
+ 15sp
+
20sp
11sp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4bf9f54a..6fca59a9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -267,6 +267,7 @@
delete userlist?
unfollow list?
\u0020Posts
+ edited
enter username
Banner Image
add banner
@@ -322,6 +323,7 @@
User favoriting this status
User liking this status
scheduled Posts
+ Edit history
now
Reply
Media preview