bug fix, updated schedule status item layout, code cleanup

This commit is contained in:
nuclearfog 2023-10-02 14:22:44 +02:00
parent 4b7c037a37
commit 5b33564f9c
No known key found for this signature in database
GPG Key ID: 03488A185C476379
19 changed files with 122 additions and 147 deletions

View File

@ -16,15 +16,6 @@
-dontwarn android.support.v8.renderscript.**
-keep,allowobfuscation, allowoptimization class android.support.v8.renderscript.** {*;}
-dontwarn org.bouncycastle.jsse.BCSSLParameters
-keep,allowobfuscation, allowoptimization class org.bouncycastle.jsse.BCSSLParameters {*;}
-dontwarn org.bouncycastle.jsse.BCSSLSocket
-keep,allowobfuscation, allowoptimization class org.bouncycastle.jsse.BCSSLSocket {*;}
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
-keep,allowobfuscation, allowoptimization class org.bouncycastle.jsse.provider.BouncyCastleJsseProvider {*;}
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
-keep,allowobfuscation, allowoptimization class org.openjsse.javax.net.ssl.SSLParameters {*;}

View File

@ -273,37 +273,6 @@
limitations under the License.
</pre>
<h3>Notices for libraries:</h3>
<ul>
<li>blurhash</li>
</ul>
<pre>
MIT License
Copyright (c) 2018 Wolt Enterprises
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software
and associated documentation files (the "Software"),
to deal in the Software without restriction,
including without limitation the rights to use,
copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software
is furnished to do so,
subject to the following conditions:
The above copyright notice and
this permission notice shall be included
in all copies or substantial portions
of the Software. THE SOFTWARE IS PROVIDED "AS IS",
WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
</pre>
<h3>Notices for libraries:</h3>
<ul>
<li>joda-time-android</li>

View File

@ -35,18 +35,22 @@ public class MastodonPoll implements Poll {
JSONArray optionArray = json.getJSONArray("options");
JSONArray voteArray = json.optJSONArray("own_votes");
JSONArray emojiArray = json.optJSONArray("emojis");
String idStr = json.getString("id");
exTime = StringUtils.getIsoTime(json.getString("expires_at"));
expired = json.getBoolean("expired");
String idStr = json.optString("id", "-1");
exTime = StringUtils.getIsoTime(json.optString("expires_at", ""));
expired = json.optBoolean("expired", false);
voted = json.optBoolean("voted", false);
multipleChoice = json.getBoolean("multiple");
multipleChoice = json.optBoolean("multiple", false);
if (!json.isNull("voters_count")) {
voteCount = json.getInt("voters_count");
}
options = new MastodonOption[optionArray.length()];
for (int i = 0; i < optionArray.length(); i++) {
JSONObject option = optionArray.getJSONObject(i);
options[i] = new MastodonOption(option);
JSONObject option = optionArray.optJSONObject(i);
if (option != null) {
options[i] = new MastodonOption(option);
} else {
options[i] = new MastodonOption(optionArray.optString(i, "-"));
}
}
if (voteArray != null) {
for (int i = 0; i < voteArray.length(); i++) {
@ -149,13 +153,20 @@ public class MastodonPoll implements Poll {
private boolean selected = false;
/**
* @param json mastodon poll json format
* @param json mastodon poll option json
*/
private MastodonOption(JSONObject json) {
voteCount = json.optInt("votes_count", 0);
title = json.optString("title", "-");
}
/**
* @param title poll option title string
*/
private MastodonOption(String title) {
this.title = title;
}
@Override
public String getTitle() {

View File

@ -116,6 +116,7 @@ public class ScheduledMastodonStatus implements ScheduledStatus {
}
@Nullable
@Override
public Poll getPoll() {
return poll;

View File

@ -1,5 +1,7 @@
package org.nuclearfog.twidda.model;
import androidx.annotation.Nullable;
import java.io.Serializable;
/**
@ -37,6 +39,7 @@ public interface ScheduledStatus extends Serializable {
/**
* @return attached poll
*/
@Nullable
Poll getPoll();
/**

View File

@ -72,12 +72,12 @@ public class AccountActivity extends AppCompatActivity implements ActivityResult
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page_fragment);
Toolbar tool = findViewById(R.id.fragment_toolbar);
root = findViewById(R.id.fragment_root);
Toolbar tool = findViewById(R.id.page_fragment_toolbar);
root = findViewById(R.id.page_fragment_root);
fragment = new AccountFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, fragment);
fragmentTransaction.replace(R.id.page_fragment_container, fragment);
fragmentTransaction.commit();
tool.setTitle(R.string.account_page);

View File

@ -39,14 +39,14 @@ public class FilterActivity extends AppCompatActivity implements FilterDialogCal
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page_filter);
ViewGroup root = findViewById(R.id.page_filter_root);
Toolbar toolbar = findViewById(R.id.page_filter_toolbar);
setContentView(R.layout.page_fragment);
ViewGroup root = findViewById(R.id.page_fragment_root);
Toolbar toolbar = findViewById(R.id.page_fragment_toolbar);
filterDialog = new FilterDialog(this, this);
fragment = new FilterFragment();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.page_filter_fragment, fragment);
fragmentTransaction.replace(R.id.page_fragment_container, fragment);
fragmentTransaction.commit();
toolbar.setTitle(R.string.toolbar_title_filter);

View File

@ -11,6 +11,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.SearchView.OnQueryTextListener;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager2.widget.ViewPager2;
@ -29,7 +30,7 @@ import org.nuclearfog.twidda.ui.views.TabSelector.OnTabSelectedListener;
*
* @author nuclearfog
*/
public class HashtagActivity extends AppCompatActivity implements SearchView.OnQueryTextListener, OnTabSelectedListener, AsyncCallback<HashtagAction.Result> {
public class HashtagActivity extends AppCompatActivity implements OnQueryTextListener, OnTabSelectedListener, AsyncCallback<HashtagAction.Result> {
private GlobalSettings settings;
private HashtagAction hashtagAction;
@ -42,7 +43,6 @@ public class HashtagActivity extends AppCompatActivity implements SearchView.OnQ
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page_tab_view);
ViewGroup root = findViewById(R.id.page_tab_view_root);
Toolbar toolbar = findViewById(R.id.page_tab_view_toolbar);
TabSelector tabSelector = findViewById(R.id.page_tab_view_tabs);
@ -82,17 +82,21 @@ public class HashtagActivity extends AppCompatActivity implements SearchView.OnQ
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem search = menu.findItem(R.id.menu_hashtag_add);
search.collapseActionView();
search.setVisible(viewPager.getCurrentItem() != 2);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
if (hashtagAction.isIdle()) {
if (viewPager.getCurrentItem() == 0) {
Toast.makeText(getApplicationContext(), R.string.info_hashtag_following,Toast.LENGTH_SHORT).show();
HashtagAction.Param param = new HashtagAction.Param(HashtagAction.Param.FOLLOW, query);
hashtagAction.execute(param, this);
return true;
} else if (viewPager.getCurrentItem() == 1) {
Toast.makeText(getApplicationContext(), R.string.info_hashtag_featuring,Toast.LENGTH_SHORT).show();
HashtagAction.Param param = new HashtagAction.Param(HashtagAction.Param.FEATURE, query);
hashtagAction.execute(param, this);
return true;

View File

@ -1,19 +1,19 @@
package org.nuclearfog.twidda.ui.activities;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.viewpager2.widget.ViewPager2;
import androidx.fragment.app.FragmentTransaction;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.ui.adapter.viewpager.ScheduleAdapter;
import org.nuclearfog.twidda.ui.fragments.ScheduleFragment;
/**
* Activity class used to show a list of scheduled posts
*
* @author nuclearfog
*/
public class ScheduleActivity extends AppCompatActivity {
@ -22,17 +22,14 @@ public class ScheduleActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.page_tab_view);
setContentView(R.layout.page_fragment);
ViewGroup root = findViewById(R.id.page_fragment_root);
Toolbar toolbar = findViewById(R.id.page_fragment_toolbar);
ViewGroup root = findViewById(R.id.page_tab_view_root);
Toolbar toolbar = findViewById(R.id.page_tab_view_toolbar);
ViewPager2 viewPager = findViewById(R.id.page_tab_view_pager);
View tabSelector = findViewById(R.id.page_tab_view_tabs);
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.page_fragment_container, ScheduleFragment.class, null);
fragmentTransaction.commit();
ScheduleAdapter adapter = new ScheduleAdapter(this);
viewPager.setAdapter(adapter);
tabSelector.setVisibility(View.GONE);
toolbar.setTitle(R.string.toolbar_schedule_title);
setSupportActionBar(toolbar);
AppStyles.setTheme(root);

View File

@ -138,6 +138,13 @@ public class IconAdapter extends Adapter<IconHolder> implements OnHolderClickLis
appendItem(IconHolder.TYPE_AUDIO);
}
/**
* append poll icon to the end
*/
public void addPollItem() {
appendItem(IconHolder.TYPE_POLL);
}
/**
*
*/

View File

@ -13,10 +13,12 @@ import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import org.nuclearfog.tag.Tagger;
import org.nuclearfog.textviewtool.LinkAndScrollMovement;
import org.nuclearfog.twidda.R;
import org.nuclearfog.twidda.backend.utils.AppStyles;
import org.nuclearfog.twidda.config.GlobalSettings;
import org.nuclearfog.twidda.model.ScheduledStatus;
import org.nuclearfog.twidda.model.Status;
import org.nuclearfog.twidda.ui.adapter.recyclerview.IconAdapter;
import java.text.SimpleDateFormat;
@ -26,7 +28,7 @@ import java.text.SimpleDateFormat;
*/
public class ScheduleHolder extends ViewHolder implements OnClickListener {
private TextView time, text;
private TextView time, text, visibility;
private RecyclerView iconList;
private IconAdapter adapter;
@ -43,6 +45,7 @@ public class ScheduleHolder extends ViewHolder implements OnClickListener {
CardView cardLayout = (CardView) itemView;
ViewGroup container = itemView.findViewById(R.id.item_schedule_container);
View removeButton = itemView.findViewById(R.id.item_schedule_delete_button);
visibility = itemView.findViewById(R.id.item_schedule_visibility);
iconList = itemView.findViewById(R.id.item_schedule_attachment);
time = itemView.findViewById(R.id.item_schedule_time);
text = itemView.findViewById(R.id.item_schedule_text);
@ -50,8 +53,10 @@ public class ScheduleHolder extends ViewHolder implements OnClickListener {
adapter = new IconAdapter(null, false);
iconList.setLayoutManager(new LinearLayoutManager(parent.getContext(), RecyclerView.HORIZONTAL, false));
iconList.setAdapter(adapter);
text.setMovementMethod(LinkAndScrollMovement.getInstance());
time.setCompoundDrawablesWithIntrinsicBounds(R.drawable.schedule, 0, 0, 0);
visibility.setCompoundDrawablesWithIntrinsicBounds(R.drawable.visibility, 0, 0, 0);
AppStyles.setTheme(container, Color.TRANSPARENT);
cardLayout.setCardBackgroundColor(settings.getCardColor());
@ -78,8 +83,22 @@ public class ScheduleHolder extends ViewHolder implements OnClickListener {
public void setContent(ScheduledStatus status) {
time.setText(SimpleDateFormat.getDateTimeInstance().format(status.getPublishTime()));
text.setText(Tagger.makeText(status.getText(), settings.getHighlightColor()));
if (status.getMedia().length > 0) {
if (status.getVisibility() == Status.VISIBLE_PRIVATE) {
visibility.setText(R.string.status_visibility_private);
visibility.setVisibility(View.VISIBLE);
} else if (status.getVisibility() == Status.VISIBLE_DIRECT) {
visibility.setText(R.string.status_visibility_direct);
visibility.setVisibility(View.VISIBLE);
} else if (status.getVisibility() == Status.VISIBLE_UNLISTED) {
visibility.setText(R.string.status_visibility_unlisted);
visibility.setVisibility(View.VISIBLE);
} else {
visibility.setVisibility(View.GONE);
}
if (status.getMedia().length > 0 || status.getPoll() != null) {
adapter.setItems(status.getMedia());
if (status.getPoll() != null)
adapter.addPollItem();
iconList.setVisibility(View.VISIBLE);
} else {
iconList.setVisibility(View.GONE);

View File

@ -1,19 +0,0 @@
package org.nuclearfog.twidda.ui.adapter.viewpager;
import androidx.fragment.app.FragmentActivity;
import org.nuclearfog.twidda.ui.fragments.ScheduleFragment;
/**
* @author nuclearfog
*/
public class ScheduleAdapter extends ViewPagerAdapter {
/**
*
*/
public ScheduleAdapter(FragmentActivity fragmentActivity) {
super(fragmentActivity);
fragments.add(new ScheduleFragment());
}
}

View File

@ -1,6 +1,6 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:width="16sp"
android:height="16sp"
android:viewportWidth="20"
android:viewportHeight="20">
<path

View File

@ -7,51 +7,63 @@
<LinearLayout
android:id="@+id/item_schedule_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/item_schedule_layout_padding">
<LinearLayout
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1">
android:orientation="horizontal"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:gravity="center_vertical">
<TextView
android:id="@+id/item_schedule_time"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:layout_weight="1"
android:lines="1"
android:drawablePadding="@dimen/item_schedule_drawable_padding"
android:textSize="@dimen/item_schedule_textsize_date" />
<TextView
android:id="@+id/item_schedule_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:maxLines="@integer/item_schedule_text_max_lines" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/item_schedule_attachment"
android:layout_width="wrap_content"
android:layout_height="@dimen/item_schedule_iconlist_height"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:layout_gravity="center" />
<ImageButton
android:id="@+id/item_schedule_delete_button"
android:layout_width="@dimen/item_schedule_button_size"
android:layout_height="@dimen/item_schedule_button_size"
android:padding="@dimen/item_schedule_button_padding"
android:layout_marginStart="@dimen/item_schedule_layout_margins"
android:contentDescription="@string/descr_remove_schedule"
android:scaleType="fitCenter"
android:src="@drawable/cross"
style="@style/RoundButton" />
</LinearLayout>
<ImageButton
android:id="@+id/item_schedule_delete_button"
android:layout_width="@dimen/item_schedule_button_size"
android:layout_height="@dimen/item_schedule_button_size"
android:padding="@dimen/item_schedule_button_padding"
<TextView
android:id="@+id/item_schedule_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:contentDescription="@string/descr_remove_schedule"
android:scaleType="fitCenter"
android:src="@drawable/cross"
style="@style/RoundButton" />
android:maxLines="@integer/item_schedule_text_max_lines"
android:fadeScrollbars="false"
android:scrollbars="vertical"/>
<TextView
android:id="@+id/item_schedule_visibility"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:drawablePadding="@dimen/item_schedule_drawable_padding"
android:textSize="@dimen/item_schedule_textsize_small"
android:lines="1"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/item_schedule_attachment"
android:layout_width="wrap_content"
android:layout_height="@dimen/item_schedule_iconlist_height"
android:layout_margin="@dimen/item_schedule_layout_margins"
android:layout_gravity="center" />
</LinearLayout>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/page_filter_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar
android:id="@+id/page_filter_toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/listpage_toolbar_height" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/page_filter_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

View File

@ -1,18 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_root"
android:id="@+id/page_fragment_root"
android:fitsSystemWindows="true"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/fragment_toolbar"
android:id="@+id/page_fragment_toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/dmpage_toolbar_height" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:id="@+id/page_fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />

View File

@ -27,7 +27,6 @@
<integer-array name="list_subscriber_tab_icons">
<item>@drawable/list</item>
<item>@drawable/user</item>
<item>@drawable/subscriber</item>
</integer-array>
<integer-array name="user_domain_exclude">

View File

@ -132,6 +132,7 @@
<dimen name="item_schedule_layout_margins">3dp</dimen>
<dimen name="item_schedule_layout_padding">5dp</dimen>
<dimen name="item_schedule_textsize_date">12sp</dimen>
<dimen name="item_schedule_textsize_small">10sp</dimen>
<dimen name="item_schedule_iconlist_height">26sp</dimen>
<dimen name="item_schedule_button_padding">1dp</dimen>
<dimen name="item_schedule_button_size">20sp</dimen>
@ -181,9 +182,6 @@
<dimen name="mainpage_toolbar_height">@dimen/toolbar_height</dimen>
<dimen name="mainpage_navigation_padding_item">20dp</dimen>
<!--dimens of page_list.xml-->
<dimen name="listpage_toolbar_height">@dimen/toolbar_height</dimen>
<!--dimens of page_list.xml-->
<dimen name="dmpage_toolbar_height">@dimen/toolbar_height</dimen>

View File

@ -22,6 +22,8 @@
<string name="info_user_removed">%1$s removed from list</string>
<string name="info_list_updated">Userlist updated</string>
<string name="info_list_created">Userlist created</string>
<string name="info_hashtag_featuring">featuring hashtag..</string>
<string name="info_hashtag_following">following hashtag..</string>
<string name="info_open_mastodon_login">redirecting to Mastodon login website. Please wait</string>
<string name="info_login_to_mastodon">login to Mastodon, please wait</string>
<string name="info_get_link">please open login page first to get the PIN</string>