diff --git a/app/build.gradle b/app/build.gradle index 8dec4173..95e47f61 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,8 +11,8 @@ android { applicationId 'org.nuclearfog.twidda' minSdkVersion 21 targetSdkVersion 33 - versionCode 93 - versionName '3.2.6' + versionCode 94 + versionName '3.3' resConfigs 'en', 'es', 'de-rDE', 'zh-rCN' } @@ -41,25 +41,25 @@ android { } dependencies { - implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'org.jsoup:jsoup:1.15.4' + implementation 'androidx.media3:media3-exoplayer:1.1.0' + implementation 'androidx.media3:media3-ui:1.1.0' + implementation 'androidx.media3:media3-datasource-okhttp:1.1.0' //noinspection GradleDependency implementation 'com.squareup.okhttp3:okhttp:4.11.0' //noinspection GradleDependency implementation 'com.squareup.picasso:picasso:2.8' - implementation 'jp.wasabeef:picasso-transformations:2.4.0' implementation 'com.github.QuadFlask:colorpicker:0.0.15' implementation 'com.github.nuclearfog:ZoomView:1.0.4' implementation 'com.github.nuclearfog:Tagger:2.4' implementation 'com.github.nuclearfog:LinkAndScrollMovement:1.4.1' implementation 'com.github.kyleduo:SwitchButton:2.0.3-SNAPSHOT' implementation 'com.github.UnifiedPush:android-connector:2.1.1' - implementation 'androidx.media3:media3-exoplayer:1.1.0' - implementation 'androidx.media3:media3-ui:1.1.0' - implementation 'androidx.media3:media3-datasource-okhttp:1.1.0' + implementation 'com.google.android.material:material:1.9.0' + implementation 'jp.wasabeef:picasso-transformations:2.4.0' + implementation 'org.jsoup:jsoup:1.15.4' } \ No newline at end of file diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java index 507a2faf..f6565226 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/Mastodon.java @@ -449,9 +449,7 @@ public class Mastodon implements Connection { @Override public Trends getTrends() throws MastodonException { - List params = new ArrayList<>(); - params.add("limit=" + settings.getListSize()); - Trends result = getTrends(ENDPOINT_TRENDS, params); + Trends result = getTrends(ENDPOINT_TRENDS, new ArrayList<>()); Collections.sort(result); return result; } @@ -461,7 +459,6 @@ public class Mastodon implements Connection { public Trends searchHashtags(String search) throws MastodonException { List params = new ArrayList<>(); params.add("q=" + StringUtils.encode(search)); - params.add("limit=" + settings.getListSize()); params.add("type=hashtags"); Trends result = getTrends(ENDPOINT_SEARCH_TIMELINE, params); Collections.sort(result); @@ -472,7 +469,6 @@ public class Mastodon implements Connection { @Override public Trends showHashtagFollowing(long cursor) throws ConnectionException { List params = new ArrayList<>(); - params.add("limit=" + settings.getListSize()); if (cursor != 0L) params.add("max_id=" + cursor); return getTrends(ENDPOINT_HASHTAG_FOLLOWING, params); @@ -661,8 +657,10 @@ public class Mastodon implements Connection { params.add("status=" + StringUtils.encode(update.getText())); if (!update.getLanguageCode().isEmpty()) params.add("language=" + update.getLanguageCode()); - if (update.getReplyId() != 0) + if (update.getReplyId() != 0L) params.add("in_reply_to_id=" + update.getReplyId()); + if (update.getScheduleTime() != 0L) + params.add("scheduled_at=" + update.getScheduleTime()); if (update.getVisibility() == Status.VISIBLE_DIRECT) params.add("visibility=direct"); else if (update.getVisibility() == Status.VISIBLE_PRIVATE) @@ -1380,6 +1378,7 @@ public class Mastodon implements Connection { */ private Trends getTrends(String endpoint, List params) throws MastodonException { try { + params.add("limit=" + settings.getListSize()); Response response = get(endpoint, params); ResponseBody body = response.body(); if (response.code() == 200 && body != null) { diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java index f04a450c..3fbc11db 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/api/mastodon/impl/MastodonUser.java @@ -135,7 +135,7 @@ public class MastodonUser implements User { @Override public String getProfileImageThumbnailUrl() { - return profileUrl; + return profileUrl; // todo switch to thumbnail url if supported by API } @@ -147,7 +147,7 @@ public class MastodonUser implements User { @Override public String getBannerImageThumbnailUrl() { - return bannerUrl; + return bannerUrl; // todo switch to thumbnail url if supported by API } @@ -171,6 +171,7 @@ public class MastodonUser implements User { @Override public boolean isVerified() { + // using getFields() instead return false; } diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/helper/update/StatusUpdate.java b/app/src/main/java/org/nuclearfog/twidda/backend/helper/update/StatusUpdate.java index 440d5837..46ae710f 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/helper/update/StatusUpdate.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/helper/update/StatusUpdate.java @@ -36,6 +36,7 @@ public class StatusUpdate implements Serializable, Closeable { // main attributes private long statusId = 0L; private long replyId = 0L; + private long scheduleTime = 0L; private boolean sensitive = false; private boolean spoiler = false; private int visibility = Status.VISIBLE_PUBLIC; @@ -199,6 +200,15 @@ public class StatusUpdate implements Serializable, Closeable { this.location = new LocationUpdate(location.getLongitude(), location.getLatitude()); } + /** + * set time to schedule the post + * + * @param scheduleTime future time + */ + public void setScheduleTime(long scheduleTime) { + this.scheduleTime = scheduleTime; + } + /** * set status visibility * @@ -338,6 +348,13 @@ public class StatusUpdate implements Serializable, Closeable { return spoiler; } + /** + * @return time to post the status + */ + public long getScheduleTime() { + return scheduleTime; + } + /** * get visibility states * diff --git a/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java b/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java index 7aa1d3f5..b0b7b875 100644 --- a/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java +++ b/app/src/main/java/org/nuclearfog/twidda/backend/utils/AppStyles.java @@ -10,6 +10,7 @@ import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.StateListDrawable; @@ -76,7 +77,7 @@ public class AppStyles { public static void setTheme(ViewGroup root) { AppStyles instance = new AppStyles(root.getContext()); root.setBackgroundColor(instance.settings.getBackgroundColor()); - instance.setSubViewTheme(root); + instance.setSubViewTheme(root, instance.settings.getBackgroundColor()); } /** @@ -88,7 +89,7 @@ public class AppStyles { public static void setTheme(ViewGroup root, @ColorInt int background) { AppStyles instance = new AppStyles(root.getContext()); root.setBackgroundColor(background); - instance.setSubViewTheme(root); + instance.setSubViewTheme(root, background); } /** @@ -99,7 +100,7 @@ public class AppStyles { */ public static void setEditorTheme(ViewGroup root, ImageView background) { AppStyles instance = new AppStyles(root.getContext()); - instance.setSubViewTheme(root); + instance.setSubViewTheme(root, instance.settings.getPopupColor()); setDrawableColor(background, instance.settings.getPopupColor()); } @@ -351,20 +352,22 @@ public class AppStyles { * parsing all views from a sub ViewGroup recursively and set all colors and fonts * * @param group current ViewGroup to parse for sub views + * @param color root background color */ - private void setSubViewTheme(ViewGroup group) { + private void setSubViewTheme(ViewGroup group, int color) { for (int pos = 0; pos < group.getChildCount(); pos++) { View child = group.getChildAt(pos); if (child instanceof SwitchButton) { SwitchButton sw = (SwitchButton) child; - int[] color = {settings.getIconColor()}; + int[] thumbColor = {settings.getIconColor()}; sw.setTintColor(settings.getHighlightColor()); - sw.setThumbColor(new ColorStateList(SWITCH_STATES, color)); + sw.setThumbColor(new ColorStateList(SWITCH_STATES, thumbColor)); } else if (child instanceof SeekBar) { SeekBar seekBar = (SeekBar) child; setSeekBarColor(seekBar, settings); } else if (child instanceof Spinner) { Spinner dropdown = (Spinner) child; + dropdown.setPopupBackgroundDrawable(new ColorDrawable(color)); setDrawableColor(dropdown.getBackground(), settings.getIconColor()); } else if (child instanceof TextView) { TextView tv = (TextView) child; @@ -389,9 +392,9 @@ public class AppStyles { if (child instanceof CardView) { CardView card = (CardView) child; card.setCardBackgroundColor(settings.getCardColor()); - setSubViewTheme(card); + setSubViewTheme(card, color); } else if (!(child instanceof ViewPager2)) { - setSubViewTheme((ViewGroup) child); + setSubViewTheme((ViewGroup) child, color); } } } diff --git a/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java b/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java index 33efbd82..54ffe252 100644 --- a/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java +++ b/app/src/main/java/org/nuclearfog/twidda/config/GlobalSettings.java @@ -132,7 +132,7 @@ public class GlobalSettings { private static final int DEFAULT_BACKGROUND_COLOR = 0xff0f114a; private static final int DEFAULT_HIGHLIGHT_COLOR = 0xffff00ff; private static final int DEFAULT_FONT_COLOR = Color.WHITE; - private static final int DEFAULT_POPUP_COLOR = 0xff19aae8; + private static final int DEFAULT_POPUP_COLOR = 0xFF0B509C; private static final int DEFAULT_CARD_COLOR = 0x40000000; private static final int DEFAULT_ICON_COLOR = Color.WHITE; private static final int DEFAULT_RT_ICON_COLOR = Color.GREEN; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusEditor.java b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusEditor.java index db5b3099..7e8f2ddf 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusEditor.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/activities/StatusEditor.java @@ -43,8 +43,8 @@ import org.nuclearfog.twidda.ui.adapter.recyclerview.IconAdapter.OnMediaClickLis import org.nuclearfog.twidda.ui.dialogs.AudioPlayerDialog; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog; import org.nuclearfog.twidda.ui.dialogs.ConfirmDialog.OnConfirmListener; -import org.nuclearfog.twidda.ui.dialogs.EmojiPicker; -import org.nuclearfog.twidda.ui.dialogs.EmojiPicker.OnEmojiSelectListener; +import org.nuclearfog.twidda.ui.dialogs.EmojiPickerDialog; +import org.nuclearfog.twidda.ui.dialogs.EmojiPickerDialog.OnEmojiSelectListener; import org.nuclearfog.twidda.ui.dialogs.PollDialog; import org.nuclearfog.twidda.ui.dialogs.PollDialog.PollUpdateCallback; import org.nuclearfog.twidda.ui.dialogs.ProgressDialog; @@ -103,7 +103,7 @@ public class StatusEditor extends MediaActivity implements ActivityResultCallbac private ProgressDialog loadingCircle; private PollDialog pollDialog; private AudioPlayerDialog audioDialog; - private EmojiPicker emojiPicker; + private EmojiPickerDialog emojiPicker; private StatusPreferenceDialog preferenceDialog; private IconAdapter adapter; @@ -140,7 +140,7 @@ public class StatusEditor extends MediaActivity implements ActivityResultCallbac preferenceDialog = new StatusPreferenceDialog(this, statusUpdate); pollDialog = new PollDialog(this, this); audioDialog = new AudioPlayerDialog(this); - emojiPicker = new EmojiPicker(this, this); + emojiPicker = new EmojiPickerDialog(this, this); adapter = new IconAdapter(this, true); iconList.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true)); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/listview/DropdownAdapter.java b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/listview/DropdownAdapter.java index a4d43f4d..e3aa5f10 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/adapter/listview/DropdownAdapter.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/adapter/listview/DropdownAdapter.java @@ -66,12 +66,11 @@ public class DropdownAdapter extends BaseAdapter { textItem.setTextColor(settings.getTextColor()); textItem.setTypeface(settings.getTypeFace()); textItem.setBackgroundColor(settings.getCardColor()); - convertView.setBackgroundColor(settings.getBackgroundColor()); } else { textItem = convertView.findViewById(R.id.dropdown_textitem); } textItem.setText(items[position]); - if (fonts.length >= items.length) { + if (position < fonts.length) { textItem.setTypeface(fonts[position]); } return convertView; diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java index 2f8e9f23..967bf0ad 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/ConfirmDialog.java @@ -13,6 +13,7 @@ import androidx.annotation.Nullable; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; +import org.nuclearfog.twidda.config.GlobalSettings; /** * Custom alert dialog class to show error and warning messages to user @@ -147,6 +148,7 @@ public class ConfirmDialog extends Dialog implements OnClickListener { private Button confirm, cancel; private OnConfirmListener listener; + private GlobalSettings settings; private int type = 0; private String messageStr = ""; @@ -156,6 +158,7 @@ public class ConfirmDialog extends Dialog implements OnClickListener { */ public ConfirmDialog(Activity activity, OnConfirmListener listener) { super(activity, R.style.ConfirmDialog); + settings = GlobalSettings.get(activity); this.listener = listener; } @@ -170,7 +173,7 @@ public class ConfirmDialog extends Dialog implements OnClickListener { title = findViewById(R.id.confirm_title); message = findViewById(R.id.confirm_message); - AppStyles.setTheme(root); + AppStyles.setTheme(root, settings.getPopupColor()); confirm.setOnClickListener(this); cancel.setOnClickListener(this); diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/DescriptionDialog.java b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/DescriptionDialog.java index f05b2b32..6410c10b 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/DescriptionDialog.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/DescriptionDialog.java @@ -12,6 +12,7 @@ import androidx.annotation.NonNull; import org.nuclearfog.twidda.R; import org.nuclearfog.twidda.backend.utils.AppStyles; +import org.nuclearfog.twidda.config.GlobalSettings; public class DescriptionDialog extends Dialog implements OnClickListener { @@ -19,12 +20,14 @@ public class DescriptionDialog extends Dialog implements OnClickListener { private static final String KEY_SAVE = " description-save"; private DescriptionCallback callback; + private GlobalSettings settings; private EditText descriptionEdit; public DescriptionDialog(Activity activity, DescriptionCallback callback) { super(activity, R.style.DefaultDialog); + settings = GlobalSettings.get(activity); this.callback = callback; } @@ -36,7 +39,7 @@ public class DescriptionDialog extends Dialog implements OnClickListener { ViewGroup root = findViewById(R.id.dialog_description_root); View applyButton = findViewById(R.id.dialog_description_apply); descriptionEdit = findViewById(R.id.dialog_description_input); - AppStyles.setTheme(root); + AppStyles.setTheme(root, settings.getPopupColor()); applyButton.setOnClickListener(this); } diff --git a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/EmojiPicker.java b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/EmojiPickerDialog.java similarity index 94% rename from app/src/main/java/org/nuclearfog/twidda/ui/dialogs/EmojiPicker.java rename to app/src/main/java/org/nuclearfog/twidda/ui/dialogs/EmojiPickerDialog.java index dd36a679..be42b0e6 100644 --- a/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/EmojiPicker.java +++ b/app/src/main/java/org/nuclearfog/twidda/ui/dialogs/EmojiPickerDialog.java @@ -31,7 +31,7 @@ import java.util.List; * * @author nuclearfog */ -public class EmojiPicker extends BottomSheetDialog implements AsyncCallback>, OnEmojiClickListener { +public class EmojiPickerDialog extends BottomSheetDialog implements AsyncCallback>, OnEmojiClickListener { private OnEmojiSelectListener listener; private EmojiAdapter adapter; @@ -41,7 +41,7 @@ public class EmojiPicker extends BottomSheetDialog implements AsyncCallback languages = new TreeMap<>(); @@ -70,9 +72,8 @@ public class StatusPreferenceDialog extends Dialog implements OnCheckedChangeLis visibilitySelector = findViewById(R.id.dialog_status_visibility); sensitiveCheck = findViewById(R.id.dialog_status_sensitive); spoilerCheck = findViewById(R.id.dialog_status_spoiler); - GlobalSettings settings = GlobalSettings.get(getContext()); - AppStyles.setTheme(rootView); + AppStyles.setTheme(rootView, settings.getPopupColor()); languageSelector.setAdapter(language_adapter); languageSelector.setSelection(0, false); languageSelector.setSelected(false); diff --git a/app/src/main/res/layout/page_settings.xml b/app/src/main/res/layout/page_settings.xml index ff5575d8..fd086fcd 100644 --- a/app/src/main/res/layout/page_settings.xml +++ b/app/src/main/res/layout/page_settings.xml @@ -311,7 +311,6 @@ android:id="@+id/spinner_font" android:layout_width="0dp" android:layout_height="wrap_content" - android:popupBackground="@android:color/transparent" app:layout_constraintStart_toStartOf="@+id/enable_status_hide_sensitive_descr" app:layout_constraintTop_toBottomOf="@id/enable_status_hide_sensitive" app:layout_constraintEnd_toStartOf="@id/spinner_scale" @@ -322,7 +321,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="@dimen/settings_spinner_margin" - android:popupBackground="@android:color/transparent" app:layout_constraintHorizontal_weight="2" app:layout_constraintStart_toEndOf="@id/spinner_font" app:layout_constraintTop_toTopOf="@id/spinner_font" @@ -509,7 +507,6 @@ android:id="@+id/spinner_woeid" android:layout_width="0dp" android:layout_height="wrap_content" - android:popupBackground="@android:color/transparent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/settings_trend_text" app:layout_constraintBottom_toBottomOf="parent"