Compare commits

..

1 Commits

Author SHA1 Message Date
LucasGGamerM
708331fca1 Adding the ability to long click or to double click the search icon to bring up the keyboard
(cherry picked from commit ee0737c9c7)
2023-01-04 21:55:19 -03:00
66 changed files with 145 additions and 770 deletions

View File

@@ -1,32 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Screenshots and screen recordings**
If applicable, add screenshots (and screen recordings, if possible) to help explain your problem.
**Version**
Megalodon version: [e.g. v1.1.4+fork.#]
**Additional context**
- Does this issue also occur with the respective upstream release? (Please test using the respective `upstream-xxxxxx.apk` provided in [Releases](https://github.com/sk22/megalodon/releases)) No / Yes (`mastodon#…`)
> In this case, please consider filing an [upstream bug report](https://github.com/mastodon/mastodon-android/issues) instead. If this bug is seriously impacting your usage or you think I might want to try to fix it for Megalodon, feel free to still create this issue!
**Crash log**
If you know your way around Android development tools, please consider attaching a crash log, if possible.

View File

@@ -1,20 +0,0 @@
---
name: Feature/UI request
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
If applicable: a clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,10 +0,0 @@
---
name: It's something else…
about: Issues that can't be categorized as feature requests or bug reports
title: ''
labels: ''
assignees: ''
---

View File

@@ -9,8 +9,8 @@ android {
applicationId "org.joinmastodon.android.moshinda"
minSdk 23
targetSdk 33
versionCode 86
versionName "1.1.4+fork.86.moshinda"
versionCode 84
versionName "1.1.4+fork.84.moshinda"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "kab", "ko-rKR", "nl-rNL", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
}

View File

@@ -1,39 +0,0 @@
# lists.d Mastodon Blocklist (c) 2022 Greyhat Academy LICENSED UNDER: CC-BY-NC-SA 4.0
# https://raw.githubusercontent.com/greyhat-academy/lists.d/main/mastodon.domains.block.list.tsv
# This list contains domains of toxic mastodon instances
# Last-Modified: 1672044500
# gab - a neonazi social network
gab.ai
gab.com
gab.protohype.net
# consequence-free speech
social.unzensiert.to
freeatlantis.com
# reactionary bigotry and hatespeech against magrinalized groups
poa.st
freespeechextremist.com
rdrama.cc
outpoa.st
anime.website
gameliberty.club
social.byoblu.com
yggdrasil.social
smuglo.li
dogeposting.social
unsafe.space
freezepeach.xyz
# + CSAM
rojogato.com
# antivaxxer shitposting & fearmongering
shadowsocial.org
# Kiwifarms
kiwifarms.net
kiwifarms.cc
kiwifarms.is
kiwifarms.pleroma.net
1 # lists.d Mastodon Blocklist (c) 2022 Greyhat Academy LICENSED UNDER: CC-BY-NC-SA 4.0
2 # https://raw.githubusercontent.com/greyhat-academy/lists.d/main/mastodon.domains.block.list.tsv
3 # This list contains domains of toxic mastodon instances
4 # Last-Modified: 1672044500
5 # gab - a neonazi social network
6 gab.ai
7 gab.com
8 gab.protohype.net
9 # consequence-free speech
10 social.unzensiert.to
11 freeatlantis.com
12 # reactionary bigotry and hatespeech against magrinalized groups
13 poa.st
14 freespeechextremist.com
15 rdrama.cc
16 outpoa.st
17 anime.website
18 gameliberty.club
19 social.byoblu.com
20 yggdrasil.social
21 smuglo.li
22 dogeposting.social
23 unsafe.space
24 freezepeach.xyz
25 # + CSAM
26 rojogato.com
27 # antivaxxer shitposting & fearmongering
28 shadowsocial.org
29 # Kiwifarms
30 kiwifarms.net
31 kiwifarms.cc
32 kiwifarms.is
33 kiwifarms.pleroma.net

View File

@@ -53,10 +53,7 @@ public class ExternalShareActivity extends FragmentStackActivity{
Intent intent=getIntent();
StringBuilder builder=new StringBuilder();
String subject = "";
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
if (!subject.isBlank()) builder.append(subject).append("\n\n");
}
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) builder.append(subject = intent.getStringExtra(Intent.EXTRA_SUBJECT)).append("\n\n");
if (intent.hasExtra(Intent.EXTRA_TEXT)) builder.append(intent.getStringExtra(Intent.EXTRA_TEXT)).append("\n");
String text=builder.toString();
List<Uri> mediaUris;

View File

@@ -32,7 +32,6 @@ public class GlobalUserPreferences{
public static boolean enableDeleteNotifications;
public static boolean relocatePublishButton;
public static boolean reduceMotion;
public static boolean keepOnlyLatestNotification;
public static String publishButtonText;
public static ThemePreference theme;
public static ColorPreference color;
@@ -70,8 +69,6 @@ public class GlobalUserPreferences{
relocatePublishButton=prefs.getBoolean("relocatePublishButton", true);
voteButtonForSingleChoice=prefs.getBoolean("voteButtonForSingleChoice", true);
enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", true);
reduceMotion=prefs.getBoolean("reduceMotion", false);
keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false);
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
recentLanguages=fromJson(prefs.getString("recentLanguages", "{}"), recentLanguagesType, new HashMap<>());
recentEmojis=fromJson(prefs.getString("recentEmojis", "{}"), recentEmojisType, new HashMap<>());
@@ -107,7 +104,6 @@ public class GlobalUserPreferences{
.putBoolean("uniformNotificationIcon", uniformNotificationIcon)
.putBoolean("enableDeleteNotifications", enableDeleteNotifications)
.putBoolean("reduceMotion", reduceMotion)
.putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification)
.putString("publishButtonText", publishButtonText)
.putInt("theme", theme.ordinal())
.putString("color", color.name())

View File

@@ -16,8 +16,7 @@ import org.joinmastodon.android.fragments.HomeFragment;
import org.joinmastodon.android.fragments.ProfileFragment;
import org.joinmastodon.android.fragments.ThreadFragment;
import org.joinmastodon.android.fragments.onboarding.AccountActivationFragment;
import org.joinmastodon.android.fragments.onboarding.CustomWelcomeFragment;
import org.joinmastodon.android.fragments.onboarding.CustomWelcomeFragment;
import org.joinmastodon.android.fragments.onboarding.CustomLoginFragment;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.joinmastodon.android.updater.GithubSelfUpdater;
@@ -34,7 +33,7 @@ public class MainActivity extends FragmentStackActivity{
if(savedInstanceState==null){
if(AccountSessionManager.getInstance().getLoggedInAccounts().isEmpty()){
showFragmentClearingBackStack(new CustomWelcomeFragment());
showFragmentClearingBackStack(new CustomLoginFragment());
}else{
AccountSessionManager.getInstance().maybeUpdateLocalInfo();
AccountSession session;

View File

@@ -38,8 +38,6 @@ public class PushNotificationReceiver extends BroadcastReceiver{
public static final int NOTIFICATION_ID=178;
private static int notificationID;
@Override
public void onReceive(Context context, Intent intent){
if(BuildConfig.DEBUG){
@@ -127,21 +125,17 @@ public class PushNotificationReceiver extends BroadcastReceiver{
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE);
}
Drawable avatar=ImageCache.getInstance(context).get(new UrlImageLoaderRequest(pn.icon, V.dp(50), V.dp(50)));
notificationID = GlobalUserPreferences.keepOnlyLatestNotification ? NOTIFICATION_ID : (int)System.currentTimeMillis();
Intent contentIntent=new Intent(context, MainActivity.class);
contentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
contentIntent.putExtra("fromNotification", true);
contentIntent.putExtra("accountID", accountID);
contentIntent.putExtra("notificationID", notificationID);
if(notification!=null){
contentIntent.putExtra("notification", Parcels.wrap(notification));
}
builder.setContentTitle(pn.title)
.setContentText(pn.body)
.setStyle(new Notification.BigTextStyle().bigText(pn.body))
.setContentIntent(PendingIntent.getActivity(context, notificationID, contentIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT))
.setContentIntent(PendingIntent.getActivity(context, accountID.hashCode() & 0xFFFF, contentIntent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT))
.setWhen(notification==null ? System.currentTimeMillis() : notification.createdAt.toEpochMilli())
.setShowWhen(true)
.setCategory(Notification.CATEGORY_SOCIAL)
@@ -166,6 +160,6 @@ public class PushNotificationReceiver extends BroadcastReceiver{
if(AccountSessionManager.getInstance().getLoggedInAccounts().size()>1){
builder.setSubText(accountName);
}
nm.notify(accountID, notificationID, builder.build());
nm.notify(accountID, NOTIFICATION_ID, builder.build());
}
}

View File

@@ -12,14 +12,11 @@ import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import org.joinmastodon.android.BuildConfig;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.api.gson.IsoInstantTypeAdapter;
import org.joinmastodon.android.api.gson.IsoLocalDateTypeAdapter;
import org.joinmastodon.android.api.session.AccountSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.time.Instant;
import java.time.LocalDate;
@@ -50,22 +47,9 @@ public class MastodonAPIController{
private static OkHttpClient httpClient=new OkHttpClient.Builder().build();
private AccountSession session;
private static List<String> badDomains = new ArrayList<>();
static{
thread.start();
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(
MastodonApp.context.getAssets().open("blocks.tsv")
));
String line;
while ((line = reader.readLine()) != null) {
if (line.isBlank() || line.startsWith("#")) continue;
badDomains.add(line.toLowerCase().trim());
}
} catch (IOException e) {
e.printStackTrace();
}
}
public MastodonAPIController(@Nullable AccountSession session){
@@ -73,11 +57,8 @@ public class MastodonAPIController{
}
public <T> void submitRequest(final MastodonAPIRequest<T> req){
final String host = req.getURL().getHost().toLowerCase();
final boolean isBad = badDomains.stream().anyMatch(host::endsWith);
thread.postRunnable(()->{
try{
if (isBad) throw new IllegalArgumentException();
if(req.canceled)
return;
Request.Builder builder=new Request.Builder()

View File

@@ -162,8 +162,6 @@ public class PushSubscriptionManager{
@Override
public void onSuccess(PushSubscription result){
MastodonAPIController.runInBackground(()->{
result.serverKey=result.serverKey.replace('/','_');
result.serverKey=result.serverKey.replace('+','-');
serverKey=deserializeRawPublicKey(Base64.decode(result.serverKey, Base64.URL_SAFE));
AccountSession session=AccountSessionManager.getInstance().tryGetAccount(accountID);

View File

@@ -1,10 +0,0 @@
package org.joinmastodon.android.api.requests.announcements;
import org.joinmastodon.android.api.MastodonAPIRequest;
public class DismissAnnouncement extends MastodonAPIRequest<Object>{
public DismissAnnouncement(String id){
super(HttpMethod.POST, "/announcements/" + id + "/dismiss", Object.class);
setRequestBody(new Object());
}
}

View File

@@ -1,15 +0,0 @@
package org.joinmastodon.android.api.requests.announcements;
import com.google.gson.reflect.TypeToken;
import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Announcement;
import java.util.List;
public class GetAnnouncements extends MastodonAPIRequest<List<Announcement>> {
public GetAnnouncements(boolean withDismissed) {
super(MastodonAPIRequest.HttpMethod.GET, "/announcements", new TypeToken<>(){});
addQueryParameter("with_dismissed", withDismissed ? "true" : "false");
}
}

View File

@@ -1,107 +0,0 @@
package org.joinmastodon.android.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageButton;
import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.announcements.GetAnnouncements;
import org.joinmastodon.android.api.requests.statuses.CreateStatus;
import org.joinmastodon.android.api.requests.statuses.GetScheduledStatuses;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.ScheduledStatusCreatedEvent;
import org.joinmastodon.android.events.ScheduledStatusDeletedEvent;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Announcement;
import org.joinmastodon.android.model.HeaderPaginationList;
import org.joinmastodon.android.model.Instance;
import org.joinmastodon.android.model.ScheduledStatus;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.joinmastodon.android.ui.utils.UiUtils;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.PaginatedList;
import me.grishka.appkit.api.SimpleCallback;
public class AnnouncementsFragment extends BaseStatusListFragment<Announcement> {
private Instance instance;
private AccountSession session;
private List<String> unreadIDs = null;
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
setTitle(R.string.sk_announcements);
session = AccountSessionManager.getInstance().getAccount(accountID);
instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
loadData();
}
@Override
protected List<StatusDisplayItem> buildDisplayItems(Announcement a) {
if(TextUtils.isEmpty(a.content)) return List.of();
Account instanceUser = new Account();
instanceUser.id = instanceUser.acct = instanceUser.username = session.domain;
instanceUser.displayName = instance.title;
instanceUser.url = "https://"+session.domain+"/about";
instanceUser.avatar = instanceUser.avatarStatic = instance.thumbnail;
instanceUser.emojis = List.of();
Status fakeStatus = a.toStatus();
return List.of(
HeaderStatusDisplayItem.fromAnnouncement(a, fakeStatus, instanceUser, this, accountID, this::onMarkAsRead),
new TextStatusDisplayItem(a.id, HtmlParser.parse(a.content, a.emojis, a.mentions, a.tags, accountID), this, fakeStatus)
);
}
public void onMarkAsRead(String id) {
if (unreadIDs == null) return;
unreadIDs.remove(id);
if (unreadIDs.size() == 0) setResult(true, null);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
protected void addAccountToKnown(Announcement s) {}
@Override
public void onItemClick(String id) {
}
@Override
protected void onDataLoaded(List<Announcement> d, boolean more) {
unreadIDs = d.stream().filter(a -> !a.read).map(a -> a.id).collect(Collectors.toList());
super.onDataLoaded(d, more);
}
@Override
protected void doLoadData(int offset, int count){
currentRequest=new GetAnnouncements(true)
.setCallback(new SimpleCallback<>(this){
@Override
public void onSuccess(List<Announcement> result){
onDataLoaded(result, false);
}
})
.exec(accountID);
}
}

View File

@@ -307,14 +307,12 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
draftsBtn=view.findViewById(R.id.drafts_btn);
draftsBtn.setVisibility(View.VISIBLE);
} else {
charCounter=view.findViewById(R.id.char_counter);
charCounter.setVisibility(View.VISIBLE);
charCounter.setText(String.valueOf(charLimit));
}
mainEditText=view.findViewById(R.id.toot_text);
mainEditTextWrap=view.findViewById(R.id.toot_text_wrap);
charCounter=view.findViewById(R.id.char_counter);
charCounter.setText(String.valueOf(charLimit));
scrollView=view.findViewById(R.id.scroll_view);
selfName=view.findViewById(R.id.self_name);
@@ -590,10 +588,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
scrollView.post(() -> {
int bottom = scrollView.getChildAt(0).getBottom();
int delta = bottom - (scrollView.getScrollY() + scrollView.getHeight());
int space = GlobalUserPreferences.reduceMotion ? 0 : Math.min(V.dp(70), delta);
int space = GlobalUserPreferences.reduceMotion ? 0 : Math.min(V.dp(120), delta);
scrollView.scrollBy(0, delta - space);
if (!GlobalUserPreferences.reduceMotion) {
scrollView.postDelayed(() -> scrollView.smoothScrollBy(0, space), 130);
scrollView.postDelayed(() -> scrollView.smoothScrollBy(0, space), 100);
}
});
}
@@ -623,7 +621,6 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
Bundle args=new Bundle();
args.putString("account", accountID);
args.putParcelable("profileAccount", Parcels.wrap(replyTo.account));
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
Nav.go(getActivity(), ProfileFragment.class, args);
});
@@ -653,10 +650,13 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
else view.findViewById(R.id.display_item_text).setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(16)));
replyText.setText(getString(R.string.in_reply_to, replyTo.account.displayName));
replyText.setContentDescription(getString(R.string.in_reply_to, replyTo.account.displayName) + ". " + getString(R.string.post_visibility) + ": " + UiUtils.getVisibilityText(replyTo));
replyText.setOnClickListener(v->{
scrollView.smoothScrollTo(0, 0);
});
int visibilityNameRes = switch (replyTo.visibility) {
case PUBLIC -> R.string.visibility_public;
case UNLISTED -> R.string.sk_visibility_unlisted;
case PRIVATE -> R.string.visibility_followers_only;
case DIRECT -> R.string.visibility_private;
};
replyText.setContentDescription(getString(R.string.in_reply_to, replyTo.account.displayName) + ". " + getString(R.string.post_visibility) + ": " + getString(visibilityNameRes));
ArrayList<String> mentions=new ArrayList<>();
String ownID=AccountSessionManager.getInstance().getAccount(accountID).self.id;
@@ -754,10 +754,6 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
draftsBtn = wrap.findViewById(R.id.drafts_btn);
draftsBtn.setVisibility(View.VISIBLE);
}else{
charCounter = wrap.findViewById(R.id.char_counter);
charCounter.setVisibility(View.VISIBLE);
charCounter.setText(String.valueOf(charLimit));
}
// draftsBtn = wrap.findViewById(R.id.drafts_btn);

View File

@@ -29,12 +29,10 @@ import com.squareup.otto.Subscribe;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.announcements.GetAnnouncements;
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
import org.joinmastodon.android.events.StatusCreatedEvent;
import org.joinmastodon.android.model.Announcement;
import org.joinmastodon.android.model.CacheablePaginatedResponse;
import org.joinmastodon.android.model.Filter;
import org.joinmastodon.android.model.Status;
@@ -58,14 +56,11 @@ import me.grishka.appkit.utils.CubicBezierInterpolator;
import me.grishka.appkit.utils.V;
public class HomeTimelineFragment extends StatusListFragment{
private static final int ANNOUNCEMENTS_RESULT = 654;
private ImageButton fab;
private ImageView toolbarLogo;
private Button toolbarShowNewPostsBtn;
private boolean newPostsBtnShown;
private AnimatorSet currentNewPostsAnim;
private MenuItem announcements;
private String maxID;
@@ -131,40 +126,16 @@ public class HomeTimelineFragment extends StatusListFragment{
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
inflater.inflate(R.menu.home, menu);
announcements = menu.findItem(R.id.announcements);
new GetAnnouncements(false).setCallback(new Callback<>() {
@Override
public void onSuccess(List<Announcement> result) {
boolean hasUnread = result.stream().anyMatch(a -> !a.read);
announcements.setIcon(hasUnread ? R.drawable.ic_announcements_24_badged : R.drawable.ic_fluent_megaphone_24_regular);
}
@Override
public void onError(ErrorResponse error) {
error.showToast(getActivity());
}
}).exec(accountID);
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
Bundle args=new Bundle();
args.putString("account", accountID);
if (item.getItemId() == R.id.settings) Nav.go(getActivity(), SettingsFragment.class, args);
if (item.getItemId() == R.id.announcements) {
Nav.goForResult(getActivity(), AnnouncementsFragment.class, args, ANNOUNCEMENTS_RESULT, this);
}
Nav.go(getActivity(), SettingsFragment.class, args);
return true;
}
@Override
public void onFragmentResult(int reqCode, boolean noMoreUnread, Bundle result){
if (reqCode == ANNOUNCEMENTS_RESULT && noMoreUnread) {
announcements.setIcon(R.drawable.ic_fluent_megaphone_24_regular);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
@@ -217,8 +188,10 @@ public class HomeTimelineFragment extends StatusListFragment{
result.get(result.size()-1).hasGapAfter=true;
toAdd=result;
}
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, Filter.FilterContext.HOME);
toAdd=toAdd.stream().filter(filterPredicate).collect(Collectors.toList());
List<Filter> filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.HOME)).collect(Collectors.toList());
if(!filters.isEmpty()){
toAdd=toAdd.stream().filter(new StatusFilterPredicate(filters)).collect(Collectors.toList());
}
if(!toAdd.isEmpty()){
prependItems(toAdd, true);
showNewPostsButton();

View File

@@ -1,11 +1,16 @@
package org.joinmastodon.android.fragments;
import static android.content.Context.CLIPBOARD_SERVICE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Fragment;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Outline;
@@ -14,6 +19,8 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.style.ImageSpan;
@@ -31,16 +38,13 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager2.widget.ViewPager2;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountByID;
@@ -79,6 +83,10 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager2.widget.ViewPager2;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.Callback;
import me.grishka.appkit.api.ErrorResponse;
@@ -98,6 +106,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
private ImageView avatar;
private CoverImageView cover;
private View avatarBorder;
private Button botIcon;
private TextView name, username, bio, followersCount, followersLabel, followingCount, followingLabel, postsCount, postsLabel;
private ProgressBarButton actionButton, notifyButton;
private ViewPager2 pager;
@@ -286,10 +295,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
followersBtn.setOnClickListener(this::onFollowersOrFollowingClick);
followingBtn.setOnClickListener(this::onFollowersOrFollowingClick);
if (account != null && account.bot) {
username.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_fluent_bot_24_filled, 0, 0, 0);
}
username.setOnLongClickListener(v->{
String usernameString=account.acct;
if(!usernameString.contains("@")){
@@ -552,15 +557,14 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
if(relationship==null && !isOwnProfile)
return;
inflater.inflate(isOwnProfile ? R.menu.profile_own : R.menu.profile, menu);
if(isOwnProfile){
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.bookmarks, R.id.followed_hashtags, R.id.favorites, R.id.scheduled, R.id.share);
}else{
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.bookmarks, R.id.followed_hashtags, R.id.favorites, R.id.scheduled);
}
UiUtils.enableOptionsMenuIcons(getActivity(), menu, R.id.bookmarks, R.id.followed_hashtags, R.id.favorites, R.id.scheduled, R.id.share, R.id.bot_icon);
menu.findItem(R.id.share).setTitle(getString(R.string.share_user, account.getShortUsername()));
if(isOwnProfile)
return;
MenuItem botIcon = menu.findItem(R.id.bot_icon);
botIcon.setVisible(account.bot);
MenuItem mute = menu.findItem(R.id.mute);
mute.setTitle(getString(relationship.muting ? R.string.unmute_user : R.string.mute_user, account.getShortUsername()));
mute.setIcon(relationship.muting ? R.drawable.ic_fluent_speaker_0_24_regular : R.drawable.ic_fluent_speaker_off_24_regular);
@@ -647,6 +651,8 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
Bundle args=new Bundle();
args.putString("account", accountID);
Nav.go(getActivity(), ScheduledStatusListFragment.class, args);
}else if(id==R.id.bot_icon){
Toast.makeText(getActivity(), R.string.sk_bot_account, Toast.LENGTH_LONG).show();
}
return true;
}

View File

@@ -131,15 +131,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
case NORD -> R.string.sk_color_palette_nord;
});
}));
items.add(new ButtonItem(R.string.sk_settings_publish_button_text, R.drawable.ic_fluent_send_24_regular, b-> {
items.add(new ButtonItem(R.string.sk_settings_publish_button_text, R.drawable.ic_fluent_send_24_regular, b->{
updatePublishText(b);
if (GlobalUserPreferences.relocatePublishButton) {
b.setOnClickListener(l -> {
Toast.makeText(getActivity(), R.string.sk_disable_relocate_publish_button_to_enable_customization,
Toast.LENGTH_LONG).show();
});
} else {
b.setOnClickListener(l -> {
b.setOnClickListener(l->{
FrameLayout inputWrap = new FrameLayout(getContext());
EditText input = new EditText(getContext());
input.setHint(R.string.publish);
@@ -159,10 +154,9 @@ public class SettingsFragment extends MastodonToolbarFragment{
GlobalUserPreferences.save();
updatePublishText(b);
})
.setNegativeButton(R.string.cancel, (d, which) -> {
})
.setNegativeButton(R.string.cancel, (d, which) -> {})
.show();
});}
});
}));
items.add(new SwitchItem(R.string.sk_settings_uniform_icon_for_notifications, R.drawable.ic_ntf_logo, GlobalUserPreferences.uniformNotificationIcon, i->{
GlobalUserPreferences.uniformNotificationIcon=i.checked;
@@ -243,10 +237,6 @@ public class SettingsFragment extends MastodonToolbarFragment{
items.add(new SwitchItem(R.string.notify_reblog, R.drawable.ic_fluent_arrow_repeat_all_24_regular, pushSubscription.alerts.reblog, i->onNotificationsChanged(PushNotification.Type.REBLOG, i.checked)));
items.add(new SwitchItem(R.string.notify_mention, R.drawable.ic_fluent_mention_24_regular, pushSubscription.alerts.mention, i->onNotificationsChanged(PushNotification.Type.MENTION, i.checked)));
items.add(new SwitchItem(R.string.sk_notify_posts, R.drawable.ic_fluent_alert_24_regular, pushSubscription.alerts.status, i->onNotificationsChanged(PushNotification.Type.STATUS, i.checked)));
items.add(new SwitchItem(R.string.sk_keep_only_latest_notification, R.drawable.ic_fluent_custom_alert_latest_24_regular, GlobalUserPreferences.keepOnlyLatestNotification, i->{
GlobalUserPreferences.keepOnlyLatestNotification=i.checked;
GlobalUserPreferences.save();
}));
items.add(new HeaderItem(R.string.settings_account));
items.add(new TextItem(R.string.sk_settings_profile, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/settings/profile"), R.drawable.ic_fluent_open_24_regular));

View File

@@ -36,10 +36,10 @@ import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
import me.grishka.appkit.utils.V;
import me.grishka.appkit.views.UsableRecyclerView;
public class CustomWelcomeFragment extends InstanceCatalogFragment {
public class CustomLoginFragment extends InstanceCatalogFragment {
private View headerView;
public CustomWelcomeFragment() {
public CustomLoginFragment() {
super(R.layout.fragment_welcome_custom, 1);
}
@@ -55,9 +55,9 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
dataLoaded();
}
@Override
// @Override
protected void onUpdateToolbar(){
super.onUpdateToolbar();
// super.onUpdateToolbar();
if (!canGoBack()) {
ImageView toolbarLogo=new ImageView(getActivity());
@@ -137,11 +137,9 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
headerView.findViewById(R.id.more).setVisibility(View.GONE);
headerView.findViewById(R.id.visibility).setVisibility(View.GONE);
headerView.findViewById(R.id.separator).setVisibility(View.GONE);
headerView.findViewById(R.id.timestamp).setVisibility(View.GONE);
headerView.findViewById(R.id.unread_indicator).setVisibility(View.GONE);
((TextView) headerView.findViewById(R.id.username)).setText(R.string.sk_app_username);
((TextView) headerView.findViewById(R.id.username)).setText("@moshidon");
((TextView) headerView.findViewById(R.id.name)).setText(R.string.sk_app_name);
((TextView) headerView.findViewById(R.id.timestamp)).setText(R.string.time_now);
((ImageView) headerView.findViewById(R.id.avatar)).setImageDrawable(getActivity().getDrawable(R.mipmap.ic_launcher));
((FragmentStackActivity) getActivity()).invalidateSystemBarColors(this);
@@ -170,7 +168,7 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
return mergeAdapter;
}
private class InstancesAdapter extends UsableRecyclerView.Adapter<InstanceViewHolder> {
private class InstancesAdapter extends UsableRecyclerView.Adapter<InstanceViewHolder>{
public InstancesAdapter(){
super(imgLoader);
}
@@ -206,6 +204,11 @@ public class CustomWelcomeFragment extends InstanceCatalogFragment {
public InstanceViewHolder(){
super(getActivity(), R.layout.item_instance_custom, list);
// itemView.setPadding(V.dp(16), V.dp(16), V.dp(16), V.dp(16));
// TypedValue value = new TypedValue();
// getActivity().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
// itemView.setBackground(getActivity().getTheme().getDrawable(R.drawable.bg_search_field));
title=findViewById(R.id.title);
description=findViewById(R.id.description);
userCount=findViewById(R.id.user_count);

View File

@@ -1,63 +0,0 @@
package org.joinmastodon.android.model;
import org.joinmastodon.android.api.RequiredField;
import org.parceler.Parcel;
import java.time.Instant;
import java.util.List;
@Parcel
public class Announcement extends BaseModel implements DisplayItemsParent {
@RequiredField
public String id;
@RequiredField
public String content;
public Instant startsAt;
public Instant endsAt;
public boolean published;
public boolean allDay;
public Instant publishedAt;
public Instant updatedAt;
public boolean read;
public List<Emoji> emojis;
public List<Mention> mentions;
public List<Hashtag> tags;
@Override
public String toString() {
return "Announcement{" +
"id='" + id + '\'' +
", content='" + content + '\'' +
", startsAt=" + startsAt +
", endsAt=" + endsAt +
", published=" + published +
", allDay=" + allDay +
", publishedAt=" + publishedAt +
", updatedAt=" + updatedAt +
", read=" + read +
", emojis=" + emojis +
", mentions=" + mentions +
", tags=" + tags +
'}';
}
public Status toStatus() {
Status s = new Status();
s.id = id;
s.mediaAttachments = List.of();
s.createdAt = startsAt != null ? startsAt : publishedAt;
if (updatedAt != null) s.editedAt = updatedAt;
s.content = s.text = content;
s.spoilerText = "";
s.visibility = StatusPrivacy.PUBLIC;
s.mentions = List.of();
s.tags = List.of();
s.emojis = List.of();
return s;
}
@Override
public String getID() {
return id;
}
}

View File

@@ -23,8 +23,7 @@ import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken;
import org.joinmastodon.android.api.session.AccountSession;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.onboarding.CustomWelcomeFragment;
import org.joinmastodon.android.fragments.onboarding.CustomWelcomeFragment;
import org.joinmastodon.android.fragments.onboarding.CustomLoginFragment;
import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.List;
@@ -78,7 +77,7 @@ public class AccountSwitcherSheet extends BottomSheet{
holder.avatar.setImageResource(R.drawable.ic_fluent_add_circle_24_filled);
holder.avatar.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(activity, android.R.attr.textColorPrimary)));
adapter.addAdapter(new ClickableSingleViewRecyclerAdapter(holder.itemView, ()->{
Nav.go(activity, CustomWelcomeFragment.class, null);
Nav.go(activity, CustomLoginFragment.class, null);
dismiss();
}));

View File

@@ -1,7 +1,6 @@
package org.joinmastodon.android.ui.displayitems;
import android.content.Context;
import android.os.Build;
import android.os.SystemClock;
import android.view.View;
import android.view.ViewGroup;
@@ -10,7 +9,6 @@ import android.widget.SeekBar;
import android.widget.TextView;
import org.joinmastodon.android.AudioPlayerService;
import org.joinmastodon.android.MastodonApp;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.Attachment;
@@ -128,10 +126,6 @@ public class AudioStatusDisplayItem extends StatusDisplayItem{
lastKnownPositionTime=SystemClock.uptimeMillis();
this.playing=playing;
playPauseBtn.setImageResource(playing ? R.drawable.ic_fluent_pause_circle_24_filled : R.drawable.ic_fluent_play_circle_24_filled);
playPauseBtn.setContentDescription(MastodonApp.context.getResources().getString(playing ? R.string.pause : R.string.play));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
playPauseBtn.setTooltipText(playPauseBtn.getContentDescription());
}
if(!playing){
lastRemainingSeconds=-1;
time.setText(formatDuration((int) item.attachment.getDuration()));

View File

@@ -2,7 +2,6 @@ package org.joinmastodon.android.ui.displayitems;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
@@ -101,11 +100,6 @@ public class ExtendedFooterStatusDisplayItem extends StatusDisplayItem{
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
case DIRECT -> R.drawable.ic_fluent_mention_24_regular;
});
visibility.setContentDescription(UiUtils.getVisibilityText(s));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
visibility.setTooltipText(visibility.getContentDescription());
}
}
@Override

View File

@@ -15,9 +15,6 @@ import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.BounceInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -61,8 +58,6 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
private final TextView reply, boost, favorite, bookmark;
private final ImageView share;
private static final Animation opacityOut, opacityIn;
private static AnimationSet animSet;
private View touchingView = null;
private boolean longClickPerformed = false;
@@ -91,15 +86,6 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
opacityIn = new AlphaAnimation(0.55f, 1);
opacityIn.setDuration(400);
opacityIn.setInterpolator(CubicBezierInterpolator.DEFAULT);
Animation spin = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
animSet = new AnimationSet(true);
animSet.setInterpolator(CubicBezierInterpolator.DEFAULT);
animSet.addAnimation(spin);
animSet.addAnimation(opacityIn);
animSet.setDuration(400);
}
public Holder(Activity activity, ViewGroup parent){
@@ -310,15 +296,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
private void onFavoriteClick(View v){
favorite.setSelected(!item.status.favourited);
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setFavorited(item.status, !item.status.favourited, r->{
if (item.status.favourited) {
if(GlobalUserPreferences.reduceMotion){
v.startAnimation(opacityIn);
}else{
v.startAnimation(animSet);
}
} else {
v.startAnimation(opacityIn);
}
v.startAnimation(opacityIn);
bindButton(favorite, r.favouritesCount);
});
}
@@ -385,4 +363,4 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
return 0;
}
}
}
}

View File

@@ -9,7 +9,6 @@ import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
@@ -24,7 +23,6 @@ import android.widget.Toast;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.announcements.DismissAnnouncement;
import org.joinmastodon.android.api.requests.statuses.CreateStatus;
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
import org.joinmastodon.android.api.session.AccountSession;
@@ -36,7 +34,6 @@ import org.joinmastodon.android.fragments.ProfileFragment;
import org.joinmastodon.android.fragments.ThreadFragment;
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Announcement;
import org.joinmastodon.android.model.Attachment;
import org.joinmastodon.android.model.Notification;
import org.joinmastodon.android.model.Relationship;
@@ -54,7 +51,6 @@ import java.time.format.FormatStyle;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import me.grishka.appkit.Nav;
import me.grishka.appkit.api.APIRequest;
@@ -78,8 +74,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
private String extraText;
private Notification notification;
private ScheduledStatus scheduledStatus;
private Announcement announcement;
private Consumer<String> consumeReadAnnouncement;
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, String extraText, Notification notification, ScheduledStatus scheduledStatus){
super(parentID, parentFragment);
@@ -108,13 +102,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
this.extraText=extraText;
}
public static HeaderStatusDisplayItem fromAnnouncement(Announcement a, Status fakeStatus, Account instanceUser, BaseStatusListFragment parentFragment, String accountID, Consumer<String> consumeReadID) {
HeaderStatusDisplayItem item = new HeaderStatusDisplayItem(a.id, instanceUser, a.startsAt, parentFragment, accountID, fakeStatus, null, null, null);
item.announcement = a;
item.consumeReadAnnouncement = consumeReadID;
return item;
}
@Override
public Type getType(){
return Type.HEADER;
@@ -134,8 +121,8 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
private final TextView name, username, timestamp, extraText, separator;
private final ImageView avatar, more, visibility, deleteNotification, unreadIndicator;
private final TextView name, username, timestamp, extraText;
private final ImageView avatar, more, visibility, deleteNotification;
private final PopupMenu optionsMenu;
private Relationship relationship;
private APIRequest<?> currentRelationshipRequest;
@@ -151,13 +138,11 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
super(activity, R.layout.display_item_header, parent);
name=findViewById(R.id.name);
username=findViewById(R.id.username);
separator=findViewById(R.id.separator);
timestamp=findViewById(R.id.timestamp);
avatar=findViewById(R.id.avatar);
more=findViewById(R.id.more);
visibility=findViewById(R.id.visibility);
deleteNotification=findViewById(R.id.delete_notification);
unreadIndicator=findViewById(R.id.unread_indicator);
extraText=findViewById(R.id.extra_text);
avatar.setOnClickListener(this::onAvaClick);
avatar.setOutlineProvider(roundCornersOutline);
@@ -282,11 +267,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
public void onBind(HeaderStatusDisplayItem item){
name.setText(item.parsedName);
username.setText('@'+item.user.acct);
separator.setVisibility(View.VISIBLE);
username.setCompoundDrawablesWithIntrinsicBounds(item.user.bot ? R.drawable.ic_fluent_bot_24_filled : 0, 0, 0, 0);
if (item.scheduledStatus!=null)
if (item.scheduledStatus.scheduledAt.isAfter(CreateStatus.DRAFTS_AFTER_INSTANT)) {
timestamp.setText(R.string.sk_draft);
@@ -294,14 +274,10 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.getDefault());
timestamp.setText(item.scheduledStatus.scheduledAt.atZone(ZoneId.systemDefault()).format(formatter));
}
else if ((item.status==null || item.status.editedAt==null) && item.createdAt != null)
else if(item.status==null || item.status.editedAt==null)
timestamp.setText(UiUtils.formatRelativeTimestamp(itemView.getContext(), item.createdAt));
else if (item.status != null && item.status.editedAt != null)
else
timestamp.setText(item.parentFragment.getString(R.string.edited_timestamp, UiUtils.formatRelativeTimestamp(itemView.getContext(), item.status.editedAt)));
else {
separator.setVisibility(View.GONE);
timestamp.setText("");
}
visibility.setVisibility(item.hasVisibilityToggle && !item.inset ? View.VISIBLE : View.GONE);
deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification!=null && !item.inset ? View.VISIBLE : View.GONE);
if(item.hasVisibilityToggle){
@@ -325,42 +301,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
currentRelationshipRequest.cancel();
}
relationship=null;
String desc;
if (item.announcement != null) {
if (unreadIndicator.getVisibility() == View.GONE) {
more.setAlpha(0f);
unreadIndicator.setAlpha(0f);
unreadIndicator.setVisibility(View.VISIBLE);
}
float alpha = item.announcement.read ? 0 : 1;
more.setImageResource(R.drawable.ic_fluent_checkmark_20_filled);
desc = item.parentFragment.getString(R.string.sk_mark_as_read);
more.animate().alpha(alpha);
unreadIndicator.animate().alpha(alpha);
more.setOnClickListener(v -> {
new DismissAnnouncement(item.announcement.id).setCallback(new Callback<>() {
@Override
public void onSuccess(Object o) {
item.consumeReadAnnouncement.accept(item.announcement.id);
item.announcement.read = true;
rebind();
}
@Override
public void onError(ErrorResponse error) {
error.showToast(item.parentFragment.getActivity());
}
}).exec(item.accountID);
});
} else {
more.setImageResource(R.drawable.ic_fluent_more_vertical_20_filled);
desc = item.parentFragment.getString(R.string.more_options);
more.setOnClickListener(this::onMoreClick);
}
more.setContentDescription(desc);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) more.setTooltipText(desc);
}
@Override
@@ -381,10 +321,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
private void onAvaClick(View v){
if (item.announcement != null) {
UiUtils.openURL(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.user.url);
return;
}
Bundle args=new Bundle();
args.putString("account", item.accountID);
args.putParcelable("profileAccount", Parcels.wrap(item.user));
@@ -416,7 +352,6 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
}
private void updateOptionsMenu(){
if (item.announcement != null) return;
boolean hasMultipleAccounts = AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1;
Menu menu=optionsMenu.getMenu();

View File

@@ -1,10 +1,8 @@
package org.joinmastodon.android.ui.text;
import android.content.Context;
import android.content.Intent;
import android.text.TextPaint;
import android.text.style.CharacterStyle;
import android.util.Log;
import android.view.View;
import org.joinmastodon.android.ui.utils.UiUtils;
@@ -44,14 +42,7 @@ public class LinkSpan extends CharacterStyle {
}
public void onLongClick(View view) {
if (getType() == Type.URL) {
Intent shareIntent = new Intent(Intent.ACTION_SEND)
.setType("text/plain")
.putExtra(Intent.EXTRA_TEXT, link);
view.getContext().startActivity(Intent.createChooser(shareIntent, null));
} else {
UiUtils.copyText(view, text);
}
UiUtils.copyText(view, getType() == Type.URL ? link : text);
}
public String getLink(){

View File

@@ -498,7 +498,7 @@ public class UiUtils{
pinned ? R.string.sk_confirm_pin_post_title : R.string.sk_confirm_unpin_post_title,
pinned ? R.string.sk_confirm_pin_post : R.string.sk_confirm_unpin_post,
pinned ? R.string.sk_pin_post : R.string.sk_unpin_post,
pinned ? R.drawable.ic_fluent_pin_28_regular : R.drawable.ic_fluent_pin_off_28_regular,
pinned ? R.drawable.ic_fluent_pin_off_28_regular : R.drawable.ic_fluent_pin_28_regular,
()->{
new SetStatusPinned(status.id, pinned)
.setCallback(new Callback<>() {
@@ -1004,13 +1004,4 @@ public class UiUtils{
return false;
}
}
public static String getVisibilityText(Status status) {
return MastodonApp.context.getString(switch (status.visibility) {
case PUBLIC -> R.string.visibility_public;
case UNLISTED -> R.string.sk_visibility_unlisted;
case PRIVATE -> R.string.visibility_followers_only;
case DIRECT -> R.string.visibility_private;
});
}
}

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_fluent_megaphone_24_regular" android:left="2dp" android:right="2dp" android:top="2dp" android:bottom="2dp"/>
<item android:width="14dp" android:height="14dp" android:gravity="top|right">
<shape android:shape="oval">
<stroke android:color="?android:colorPrimary" android:width="2dp"/>
<solid android:color="?android:colorAccent"/>
</shape>
</item>
</layer-list>

View File

@@ -1,3 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M14.69 11.503c1 0 1.81 0.81 1.81 1.81v0.689h-0.005c-0.034 0.78-0.248 1.757-1.123 2.555C14.416 17.43 12.765 18 10 18c-2.766 0-4.416-0.57-5.372-1.443-0.875-0.798-1.089-1.776-1.123-2.555H3.5v-0.69c0-0.999 0.81-1.809 1.81-1.809h9.38zM6.5 3C5.672 3 5 3.672 5 4.5v4C5 9.328 5.672 10 6.5 10h7c0.828 0 1.5-0.672 1.5-1.5v-4C15 3.672 14.328 3 13.5 3h-3V2.5C10.5 2.191 10.276 2 10 2S9.5 2.23 9.5 2.5V3h-3zM7 6.5c0-0.552 0.448-1 1-1s1 0.448 1 1-0.448 1-1 1-1-0.448-1-1zm4 0c0-0.552 0.448-1 1-1s1 0.448 1 1-0.448 1-1 1-1-0.448-1-1z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -3,7 +3,7 @@
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M12,5.5C11.448,5.5 11,5.948 11,6.5C11,7.052 11.448,7.5 12,7.5C12.552,7.5 13,7.052 13,6.5C13,5.948 12.552,5.5 12,5.5ZM7,6.5C7,5.948 7.448,5.5 8,5.5C8.552,5.5 9,5.948 9,6.5C9,7.052 8.552,7.5 8,7.5C7.448,7.5 7,7.052 7,6.5ZM10.5,2.5C10.5,2.224 10.276,2 10,2C9.724,2 9.5,2.224 9.5,2.5V3H6.5C5.672,3 5,3.672 5,4.5V8.5C5,9.328 5.672,10 6.5,10H13.5C14.328,10 15,9.328 15,8.5V4.5C15,3.672 14.328,3 13.5,3H10.5V2.5ZM6.5,4H13.5C13.776,4 14,4.224 14,4.5V8.5C14,8.776 13.776,9 13.5,9H6.5C6.224,9 6,8.776 6,8.5V4.5C6,4.224 6.224,4 6.5,4ZM10.25,17.998C12.866,17.965 14.445,17.403 15.372,16.557C16.247,15.759 16.461,14.781 16.495,14.002H16.5V13.312C16.5,12.313 15.69,11.503 14.691,11.503H11.5V11.5H8.5V11.503H5.309C4.31,11.503 3.5,12.313 3.5,13.312V14.002H3.505C3.539,14.781 3.753,15.759 4.628,16.557C5.555,17.403 7.134,17.965 9.75,17.998V18H10.25V17.998ZM5.309,12.503H14.691C15.138,12.503 15.5,12.865 15.5,13.312V13.75C15.5,14.44 15.369,15.206 14.698,15.819C14.01,16.446 12.66,17 10,17C7.339,17 5.99,16.446 5.302,15.819C4.631,15.206 4.5,14.44 4.5,13.75V13.312C4.5,12.865 4.862,12.503 5.309,12.503Z"
android:fillColor="@color/fluent_default_icon_tint"/>
<path
android:pathData="M12,5.5C11.448,5.5 11,5.948 11,6.5C11,7.052 11.448,7.5 12,7.5C12.552,7.5 13,7.052 13,6.5C13,5.948 12.552,5.5 12,5.5ZM7,6.5C7,5.948 7.448,5.5 8,5.5C8.552,5.5 9,5.948 9,6.5C9,7.052 8.552,7.5 8,7.5C7.448,7.5 7,7.052 7,6.5ZM10.5,2.5C10.5,2.224 10.276,2 10,2C9.724,2 9.5,2.224 9.5,2.5V3H6.5C5.672,3 5,3.672 5,4.5V8.5C5,9.328 5.672,10 6.5,10H13.5C14.328,10 15,9.328 15,8.5V4.5C15,3.672 14.328,3 13.5,3H10.5V2.5ZM6.5,4H13.5C13.776,4 14,4.224 14,4.5V8.5C14,8.776 13.776,9 13.5,9H6.5C6.224,9 6,8.776 6,8.5V4.5C6,4.224 6.224,4 6.5,4ZM10.25,17.998C12.866,17.965 14.445,17.403 15.372,16.557C16.247,15.759 16.461,14.781 16.495,14.002H16.5V13.312C16.5,12.313 15.69,11.503 14.691,11.503H11.5V11.5H8.5V11.503H5.309C4.31,11.503 3.5,12.313 3.5,13.312V14.002H3.505C3.539,14.781 3.753,15.759 4.628,16.557C5.555,17.403 7.134,17.965 9.75,17.998V18H10.25V17.998ZM5.309,12.503H14.691C15.138,12.503 15.5,12.865 15.5,13.312V13.75C15.5,14.44 15.369,15.206 14.698,15.819C14.01,16.446 12.66,17 10,17C7.339,17 5.99,16.446 5.302,15.819C4.631,15.206 4.5,14.44 4.5,13.75V13.312C4.5,12.865 4.862,12.503 5.309,12.503Z"
android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M17.753,14a2.25,2.25 0,0 1,2.25 2.25v0.905a3.75,3.75 0,0 1,-1.307 2.846C17.13,21.345 14.89,22 12,22c-2.89,0 -5.128,-0.656 -6.691,-2a3.75,3.75 0,0 1,-1.306 -2.843v-0.908A2.25,2.25 0,0 1,6.253 14h11.5ZM11.898,2.008 L12,2a0.75,0.75 0,0 1,0.743 0.648l0.007,0.102L12.75,3.5h3.5a2.25,2.25 0,0 1,2.25 2.25v4.505a2.25,2.25 0,0 1,-2.25 2.25h-8.5a2.25,2.25 0,0 1,-2.25 -2.25L5.5,5.75A2.25,2.25 0,0 1,7.75 3.5h3.5v-0.749a0.75,0.75 0,0 1,0.648 -0.743L12,2l-0.102,0.007ZM9.75,6.5a1.25,1.25 0,1 0,0 2.5,1.25 1.25,0 0,0 0,-2.5ZM14.243,6.5a1.25,1.25 0,1 0,0 2.499,1.25 1.25,0 0,0 0,-2.499Z"
android:fillColor="?android:textColorPrimary"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M17.753,13.999C18.996,13.999 20.003,15.007 20.003,16.249V17.154C20.003,18.248 19.526,19.287 18.696,20C17.131,21.344 14.89,22.001 12,22.001C9.111,22.001 6.872,21.344 5.309,20C4.481,19.288 4.004,18.25 4.004,17.157V16.249C4.004,15.007 5.011,13.999 6.254,13.999H17.753ZM17.753,15.499H6.254C5.84,15.499 5.504,15.835 5.504,16.249V17.157C5.504,17.812 5.79,18.435 6.287,18.863C7.545,19.944 9.441,20.501 12,20.501C14.56,20.501 16.458,19.944 17.719,18.862C18.217,18.434 18.503,17.811 18.503,17.154V16.249C18.503,15.835 18.168,15.499 17.753,15.499ZM11.899,2.007L12.001,2C12.38,2 12.694,2.282 12.744,2.648L12.751,2.75L12.75,3.499L16.25,3.5C17.493,3.5 18.5,4.507 18.5,5.75V10.254C18.5,11.497 17.493,12.504 16.25,12.504H7.75C6.508,12.504 5.5,11.497 5.5,10.254V5.75C5.5,4.507 6.508,3.5 7.75,3.5L11.25,3.499L11.251,2.75C11.251,2.37 11.533,2.057 11.899,2.007L12.001,2L11.899,2.007ZM16.25,5H7.75C7.336,5 7,5.335 7,5.75V10.254C7,10.668 7.336,11.004 7.75,11.004H16.25C16.665,11.004 17,10.668 17,10.254V5.75C17,5.335 16.665,5 16.25,5ZM9.75,6.5C10.44,6.5 10.999,7.059 10.999,7.749C10.999,8.439 10.44,8.998 9.75,8.998C9.06,8.998 8.5,8.439 8.5,7.749C8.5,7.059 9.06,6.5 9.75,6.5ZM14.242,6.5C14.932,6.5 15.492,7.059 15.492,7.749C15.492,8.439 14.932,8.998 14.242,8.998C13.552,8.998 12.993,8.439 12.993,7.749C12.993,7.059 13.552,6.5 14.242,6.5Z"
android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,15 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M9.562,3C5.419,3 2.062,6.358 2.062,10.5C2.062,11.633 2.313,12.709 2.764,13.673C2.51,14.671 2.226,15.784 2.04,16.515C1.807,17.428 2.629,18.259 3.544,18.039C4.294,17.859 5.447,17.582 6.474,17.337C7.417,17.763 8.462,18 9.562,18C13.704,18 17.062,14.642 17.062,10.5C17.062,6.358 13.704,3 9.562,3ZM3.562,10.5C3.562,7.186 6.248,4.5 9.562,4.5C12.875,4.5 15.562,7.186 15.562,10.5C15.562,13.814 12.875,16.5 9.562,16.5C8.601,16.5 7.695,16.275 6.892,15.875L6.648,15.754L6.384,15.817C5.461,16.036 4.395,16.292 3.596,16.484C3.795,15.705 4.058,14.672 4.286,13.776L4.356,13.5L4.226,13.247C3.801,12.425 3.562,11.491 3.562,10.5ZM14.562,21C12.592,21 10.8,20.241 9.462,19C9.495,19 9.528,19 9.562,19C10.28,19 10.977,18.911 11.643,18.743C12.507,19.225 13.502,19.5 14.562,19.5C15.522,19.5 16.428,19.275 17.232,18.875L17.475,18.754L17.74,18.817C18.661,19.036 19.705,19.263 20.479,19.426C20.304,18.676 20.065,17.671 19.837,16.776L19.767,16.5L19.897,16.247C20.322,15.425 20.562,14.491 20.562,13.5C20.562,11.385 19.468,9.526 17.815,8.458C17.636,7.734 17.365,7.048 17.015,6.411C19.952,7.427 22.062,10.217 22.062,13.5C22.062,14.633 21.81,15.709 21.359,16.674C21.612,17.682 21.868,18.774 22.03,19.477C22.235,20.362 21.455,21.163 20.563,20.977C19.836,20.825 18.693,20.581 17.649,20.337C16.707,20.763 15.661,21 14.562,21Z"
android:fillColor="@color/fluent_default_icon_tint" />
<path
android:pathData="M7.297,8.312L11.85,8.312A0.75,0.75 0,0 1,12.6 9.062L12.6,9.062A0.75,0.75 0,0 1,11.85 9.812L7.297,9.812A0.75,0.75 0,0 1,6.547 9.062L6.547,9.062A0.75,0.75 0,0 1,7.297 8.312z"
android:fillColor="@color/fluent_default_icon_tint" />
<path
android:pathData="M7.297,11.312L10.323,11.312A0.75,0.75 0,0 1,11.073 12.062L11.073,12.062A0.75,0.75 0,0 1,10.323 12.812L7.297,12.812A0.75,0.75 0,0 1,6.547 12.062L6.547,12.062A0.75,0.75 0,0 1,7.297 11.312z"
android:fillColor="@color/fluent_default_icon_tint" />
</vector>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--~ Copyright (c) 2022. ~ Microsoft Corporation. All rights reserved.-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_fluent_chat_multiple_24_regular_text" android:state_selected="true"/>
<item android:drawable="@drawable/ic_fluent_chat_multiple_24_regular"/>
</selector>

View File

@@ -1,3 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M7.032 13.907l-3.471-3.905C3.285 9.692 2.81 9.664 2.5 9.939 2.193 10.215 2.165 10.69 2.44 11l4 4.5c0.287 0.322 0.786 0.336 1.091 0.031l10.5-10.5c0.293-0.293 0.293-0.767 0-1.06-0.293-0.293-0.767-0.293-1.06 0l-9.938 9.937z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,3 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M13 10c0 1.657-1.343 3-3 3s-3-1.343-3-3 1.343-3 3-3 3 1.343 3 3z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/fluent_default_icon_tint"
android:pathData="M12,1.996C7.852,1.996 4.5,5.341 4.5,9.496L4.5,13.594L3.129,16.752A1.251,1.251 0,0 0,4.275 18.5L9,18.5L9.006,18.68A3,3 0,0 0,15 18.502L19.736,18.5A1.25,1.25 0,0 0,20.881 16.75L19.5,13.594L19.5,12.668A6.5,6.5 0,0 1,18 12.955L18,13.906L19.354,17L4.656,17L6,13.906L6,9.496C6,6.253 8.549,3.631 11.754,3.502A6.5,6.5 0,0 1,12.793 2.051A7.49,7.49 0,0 0,12 1.996zM13.5,18.5L13.494,18.646A1.5,1.5 0,0 1,10.5 18.502L13.5,18.5z" />
<path
android:fillColor="@color/fluent_default_icon_tint"
android:pathData="m17.5,2.189a4.311,4.311 0,1 0,4.282 3.809c-0.04,-0.35 0.213,-0.687 0.565,-0.687 0.306,0 0.576,0.213 0.612,0.517A5.5,5.5 0,1 1,20.918 2.191V1.891a0.595,0.595 0,1 1,1.19 0v1.604l0.02,0.031h-0.02V3.675A0.595,0.595 0,0 1,21.513 4.27h-1.784a0.595,0.595 0,1 1,0 -1.189h0.396a4.292,4.292 0,0 0,-2.626 -0.892z" />
</vector>

View File

@@ -1,3 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M21.907 5.622C21.969 5.83 22 6.046 22 6.263V17.74c0 1.242-1.007 2.25-2.25 2.25-0.217 0-0.433-0.032-0.641-0.094l-5.514-1.64C12.938 19.602 11.558 20.5 10 20.5c-2.142 0-3.891-1.683-3.995-3.8L6 16.5 5.999 16l-2.39-0.711C2.655 15.004 2 14.127 2 13.131V10.87c0-0.995 0.655-1.873 1.61-2.156l15.5-4.606c1.19-0.355 2.443 0.324 2.797 1.515zM7.499 16.445L7.5 16.499C7.5 17.88 8.62 19 10 19c0.885 0 1.678-0.464 2.124-1.179l-4.625-1.375zm12.037-10.9l-15.5 4.605C3.718 10.245 3.5 10.537 3.5 10.87v2.261c0 0.332 0.218 0.625 0.536 0.72l15.5 4.607c0.07 0.02 0.142 0.03 0.214 0.03 0.414 0 0.75-0.335 0.75-0.75V6.264c0-0.072-0.01-0.144-0.031-0.213-0.118-0.397-0.536-0.624-0.933-0.506z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,3 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M10 6.5c-0.966 0-1.75-0.784-1.75-1.75S9.034 3 10 3s1.75 0.784 1.75 1.75S10.966 6.5 10 6.5zM10 17c-0.966 0-1.75-0.784-1.75-1.75S9.034 13.5 10 13.5s1.75 0.784 1.75 1.75S10.966 17 10 17zm-1.75-7c0 0.966 0.784 1.75 1.75 1.75s1.75-0.784 1.75-1.75S10.966 8.25 10 8.25 8.25 9.034 8.25 10z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
@@ -19,8 +18,6 @@
<ImageView
android:id="@+id/send_error"
android:tooltipText="@string/sk_sending_error"
android:contentDescription="@string/sk_sending_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
@@ -55,16 +52,6 @@
android:contentDescription="@string/sk_schedule_or_draft"
android:tooltipText="@string/sk_schedule_or_draft" />
<TextView
android:id="@+id/char_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/m3_body_large"
android:textColor="?android:textColorSecondary"
android:layout_marginHorizontal="8dp"
android:visibility="gone"
tools:text="500"/>
<Button
android:id="@+id/publish_btn"
android:layout_width="wrap_content"

View File

@@ -28,8 +28,6 @@
android:layout_marginTop="2dp"
android:layout_marginStart="2dp"
android:background="?android:selectableItemBackgroundBorderless"
android:contentDescription="@string/delete"
android:tooltipText="@string/delete"
android:tint="#D92C2C"
android:src="@drawable/ic_fluent_delete_20_regular"/>
@@ -107,7 +105,7 @@
android:layout_below="@id/retry_or_cancel_upload"
android:layout_marginTop="16dp"
android:textColor="?colorGray200"
android:textSize="14sp"
android:textSize="14dp"
android:gravity="center_horizontal"
android:singleLine="true"
android:ellipsize="end"
@@ -139,7 +137,6 @@
android:background="?android:selectableItemBackgroundBorderless"
android:tint="#D92C2C"
android:contentDescription="@string/delete"
android:tooltipText="@string/delete"
android:src="@drawable/ic_fluent_delete_20_regular"/>
</FrameLayout>

View File

@@ -20,7 +20,6 @@
android:layout_height="24dp"
android:layout_margin="16dp"
android:tint="?colorDarkIcon"
android:importantForAccessibility="no"
android:src="@drawable/ic_fluent_circle_24_regular"/>
<EditText
android:id="@+id/edit"
@@ -42,7 +41,6 @@
android:layout_height="56dp"
android:scaleType="center"
android:tint="?colorDarkIcon"
android:contentDescription="@string/reorder"
android:src="@drawable/ic_fluent_re_order_dots_vertical_24_regular"/>
</LinearLayout>

View File

@@ -17,7 +17,7 @@
android:layout_width="wrap_content"
android:layout_height="24dp"
android:layout_gravity="center"
android:drawableStart="@drawable/ic_fluent_chat_multiple_24_selector_text"
android:drawableStart="@drawable/ic_fluent_chat_multiple_24_regular"
android:drawablePadding="8dp"
android:drawableTint="?android:textColorSecondary"
android:gravity="center_vertical"

View File

@@ -18,7 +18,7 @@
android:background="?android:selectableItemBackgroundBorderless"
android:contentDescription="@string/more_options"
android:scaleType="center"
android:src="@drawable/ic_fluent_more_vertical_20_filled"
android:src="@drawable/ic_post_more"
android:tint="?android:textColorSecondary" />
<ImageView
@@ -47,21 +47,10 @@
android:src="@drawable/ic_visibility"
android:tint="?android:textColorSecondary" />
<ImageView
android:id="@+id/unread_indicator"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginTop="-6dp"
android:layout_toStartOf="@id/visibility"
android:visibility="gone"
android:tint="?android:colorAccent"
android:scaleType="center"
android:src="@drawable/ic_fluent_circle_small_20_filled" />
<ImageView
android:id="@+id/avatar"
android:layout_width="46sp"
android:layout_height="46sp"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="12dp" />
@@ -69,17 +58,15 @@
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
android:id="@+id/name_wrap"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="24dp"
android:layout_marginEnd="12dp"
android:layout_marginTop="2sp"
android:layout_toStartOf="@id/unread_indicator"
android:layout_toEndOf="@id/avatar"
android:minHeight="24sp">
android:layout_toStartOf="@id/visibility"
android:layout_toEndOf="@id/avatar">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="24dp"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"
@@ -89,7 +76,7 @@
<TextView
android:id="@+id/extra_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:fontFamily="sans-serif"
@@ -102,19 +89,18 @@
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="20dp"
android:layout_below="@id/name_wrap"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@id/unread_indicator"
android:layout_toStartOf="@id/visibility"
android:layout_toEndOf="@id/avatar"
android:layoutDirection="locale"
android:minHeight="20sp"
android:orientation="horizontal">
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="20dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_small"
@@ -123,9 +109,9 @@
<TextView
android:id="@+id/separator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4sp"
android:layout_marginRight="4sp"
android:layout_height="20dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:importantForAccessibility="no"
android:text="·"
android:textAppearance="@style/m3_title_small" />
@@ -133,7 +119,7 @@
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="20dp"
android:singleLine="true"
android:textAppearance="@style/m3_title_small"
tools:text="3h" />

View File

@@ -56,10 +56,10 @@
<TextView
android:id="@+id/reply_text"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-12dp"
android:layout_marginStart="16dp"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:paddingBottom="6dp"
android:textAppearance="@style/m3_title_small"
@@ -68,7 +68,8 @@
android:drawableTint="?android:textColorSecondary"
android:drawablePadding="6dp"
android:singleLine="true"
android:ellipsize="end"/>
android:ellipsize="end"
android:background="?android:selectableItemBackground"/>
<RelativeLayout
android:layout_width="match_parent"
@@ -79,8 +80,8 @@
<ImageView
android:id="@+id/self_avatar"
android:layout_width="46sp"
android:layout_height="46sp"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="12dp" />
@@ -88,9 +89,8 @@
<TextView
android:id="@+id/self_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="24dp"
android:layout_toEndOf="@id/self_avatar"
android:minHeight="24sp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
@@ -99,10 +99,9 @@
<TextView
android:id="@+id/self_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="20dp"
android:layout_below="@id/self_name"
android:layout_toEndOf="@id/self_avatar"
android:minHeight="20sp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_small"
@@ -154,7 +153,6 @@
android:layout_marginBottom="8dp"
android:background="@drawable/bg_poll_option_clickable"
android:outlineProvider="background"
android:contentDescription="@string/sk_poll_option_add"
android:elevation="2dp">
<ImageView
android:id="@+id/add_poll_option_icon"
@@ -162,7 +160,6 @@
android:layout_height="24dp"
android:layout_margin="16dp"
android:tint="?colorDarkIcon"
android:importantForAccessibility="no"
android:src="@drawable/ic_fluent_add_circle_24_regular"/>
</LinearLayout>
<TextView
@@ -423,7 +420,6 @@
android:layout_height="wrap_content"
android:textAppearance="@style/m3_body_large"
android:textColor="?android:textColorSecondary"
android:visibility="gone"
tools:text="500"/>
<Button
@@ -433,7 +429,6 @@
android:layout_marginStart="12dp"
android:visibility="gone"
android:tooltipText="@string/publish"
android:contentDescription="@string/publish"
android:drawableStart="@drawable/ic_fluent_send_24_selector"
/>

View File

@@ -36,7 +36,7 @@
android:hint="@string/search_hint"
android:textColorHint="?colorSearchHint"
android:textColor="?android:textColorPrimary"
android:textSize="16sp"
android:textSize="16dp"
android:singleLine="true"
android:inputType="textFilter"
android:imeOptions="actionSearch"

View File

@@ -45,7 +45,7 @@
android:textColor="?colorGray50t"
android:textAllCaps="true"
android:fontFamily="sans-serif-medium"
android:textSize="14sp"
android:textSize="14dp"
android:gravity="center"
android:background="@drawable/bg_profile_follows_you"
android:visibility="gone"
@@ -318,11 +318,7 @@
</LinearLayout>
</org.joinmastodon.android.ui.views.NestedRecyclerScrollView>
<ImageButton
android:tooltipText="@string/sk_fab_compose"
android:contentDescription="@string/sk_fab_compose"
android:id="@+id/fab"
style="@style/Widget.Mastodon.Button.Compose"/>
<ImageButton android:id="@+id/fab" style="@style/Widget.Mastodon.Button.Compose"/>
</FrameLayout>
</me.grishka.appkit.views.RecursiveSwipeRefreshLayout>

View File

@@ -14,7 +14,8 @@
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="12dp"
android:text="@string/sk_welcome_title" />
android:text="@string/sk_welcome_title"
/>
<TextView
style="@style/m3_body_large"

View File

@@ -19,7 +19,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="24dp"
android:textSize="16sp"
android:textSize="16dp"
android:textColor="?android:textColorPrimary"
android:singleLine="true"
android:ellipsize="end"/>

View File

@@ -91,7 +91,6 @@
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:gravity="center_horizontal"
android:layout_weight="1"
android:orientation="vertical">
<TextView
@@ -116,7 +115,6 @@
android:layout_marginTop="16dp"
android:layout_marginStart="12dp"
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center_horizontal">
<TextView
android:id="@+id/followers_count"
@@ -140,7 +138,6 @@
android:layout_marginTop="16dp"
android:layout_marginStart="12dp"
android:orientation="vertical"
android:layout_weight="1"
android:gravity="center_horizontal">
<TextView
android:id="@+id/following_count"
@@ -228,9 +225,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:padding="8dp"
android:layout_weight="1"
android:clipToPadding="false">
<org.joinmastodon.android.ui.views.ProgressBarButton

View File

@@ -6,7 +6,7 @@
android:singleLine="true"
android:ellipsize="end"
android:fontFamily="sans-serif-medium"
android:textSize="12sp"
android:textSize="12dp"
android:textColor="?android:textColorSecondary"
android:textAllCaps="true"
android:paddingTop="24dp"

View File

@@ -11,7 +11,6 @@
android:id="@+id/emoji"
android:layout_width="24dp"
android:layout_height="24dp"
android:importantForAccessibility="no"
android:layout_marginBottom="6dp"
android:layout_gravity="center_horizontal"/>
@@ -23,7 +22,7 @@
android:textAllCaps="true"
android:textColor="?android:textColorPrimary"
android:fontFamily="sans-serif-medium"
android:textSize="14sp"
android:textSize="14dp"
android:gravity="center_vertical"
android:singleLine="true"
android:ellipsize="end"

View File

@@ -11,7 +11,6 @@
android:layout_height="24dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:importantForAccessibility="no"
android:tint="?android:textColorSecondary"
android:src="@drawable/ic_round_checkbox"/>

View File

@@ -12,13 +12,13 @@
<TextView
android:id="@+id/number"
android:layout_width="24sp"
android:layout_height="wrap_content"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="16dp"
android:textColor="?android:colorAccent"
android:fontFamily="sans-serif-condensed"
android:textStyle="bold"
android:textSize="22sp"
android:textSize="22dp"
android:gravity="center"
android:includeFontPadding="false"
tools:text="1"/>

View File

@@ -14,7 +14,7 @@
android:layout_marginEnd="8dp"
android:gravity="center_vertical"
android:textColor="?android:textColorPrimary"
android:textSize="20sp"
android:textSize="20dp"
android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:ellipsize="end"
@@ -26,7 +26,7 @@
android:layout_height="32dp"
android:background="@drawable/bg_inline_button"
android:textColor="?android:textColorPrimary"
android:textSize="20sp"
android:textSize="20dp"
android:fontFamily="sans-serif-medium"
android:paddingLeft="4dp"
android:paddingRight="4dp"

View File

@@ -28,7 +28,6 @@
/>
<ImageView
android:id="@+id/icon"
android:importantForAccessibility="no"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -10,7 +10,6 @@
android:layout_width="100dp"
android:layout_height="121dp"
android:elevation="1dp"
android:importantForAccessibility="no"
android:foreground="?android:selectableItemBackground"
android:duplicateParentState="true"
tools:src="@drawable/theme_auto"/>

View File

@@ -20,10 +20,6 @@
android:layout_height="match_parent"
android:id="@+id/empty"/>
<ImageButton
android:contentDescription="@string/sk_fab_compose"
android:tooltipText="@string/sk_fab_compose"
android:id="@+id/fab"
style="@style/Widget.Mastodon.Button.Compose"/>
<ImageButton android:id="@+id/fab" style="@style/Widget.Mastodon.Button.Compose"/>
</FrameLayout>
</me.grishka.appkit.views.RecursiveSwipeRefreshLayout>

View File

@@ -71,7 +71,6 @@
android:layout_width="28dp"
android:layout_height="28dp"
android:layout_gravity="center"
android:importantForAccessibility="no"
android:scaleType="centerCrop"
android:src="@null"/>
<View

View File

@@ -1,10 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/announcements"
android:icon="@drawable/ic_fluent_megaphone_24_regular"
android:showAsAction="always"
android:title="@string/sk_announcements" />
<item
android:id="@+id/settings"
android:icon="@drawable/ic_fluent_settings_24_regular"

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/bot_icon" android:title="@string/sk_bot_account" android:icon="@drawable/ic_fluent_bot_24_regular" android:showAsAction="always"/>
<item android:id="@+id/share" android:title="@string/share_user" android:icon="@drawable/ic_fluent_share_24_regular"/>
<item android:id="@+id/mute" android:title="@string/mute_user" android:icon="@drawable/ic_fluent_speaker_mute_24_regular"/>
<item android:id="@+id/block" android:title="@string/block_user" android:icon="@drawable/ic_fluent_person_prohibited_24_regular"/>

View File

@@ -4,14 +4,14 @@
<string name="sk_pinned_posts">Angeheftet</string>
<string name="sk_delete_and_redraft">Löschen und neu erstellen</string>
<string name="sk_confirm_delete_and_redraft_title">Beitrag löschen und neu erstellen</string>
<string name="sk_confirm_delete_and_redraft">Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest\?</string>
<string name="sk_confirm_delete_and_redraft">Bist du dir sicher, dass du diesen Beitrag löschen und neu erstellen möchtest?</string>
<string name="sk_pin_post">An Profil anheften</string>
<string name="sk_confirm_pin_post_title">Beitrag an Profil anheften</string>
<string name="sk_confirm_pin_post">Möchtest du den Beitrag an dein Profil anheften?</string>
<string name="sk_pinning">Wird angeheftet…</string>
<string name="sk_unpin_post">Von Profil lösen</string>
<string name="sk_confirm_unpin_post_title">Angehefteten Beitrag von Profil lösen</string>
<string name="sk_confirm_unpin_post">Bist du dir sicher, dass du den angehefteten Beitrag von deinem Profil lösen möchtest\?</string>
<string name="sk_confirm_unpin_post">Bist du dir sicher, dass du den angehefteten Beitrag von deinem Profil lösen möchtest?</string>
<string name="sk_unpinning">Wird vom Profil gelöst…</string>
<string name="sk_image_description">Bildbeschreibung</string>
<string name="sk_visibility_unlisted">Nicht gelistet</string>
@@ -37,7 +37,7 @@
<string name="sk_lists_with_user">Listen mit %s</string>
<string name="sk_settings_always_reveal_content_warnings">Inhaltswarnungen immer ausklappen</string>
<string name="sk_disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
<string name="sk_disable_dividers">Beitrags Trennung deaktivieren</string>
<string name="sk_disable_dividers">Tröt Trennung deaktivieren</string>
<string name="sk_relocate_publish_button">Veröffentlichen Schaltfläche verschieben</string>
<string name="sk_settings_contribute">Zu Moshidon beitragen</string>
<string name="sk_settings_show_federated_timeline">Föderierte Timeline anzeigen</string>
@@ -75,10 +75,10 @@
<string name="sk_settings_donate">Spenden</string>
<string name="sk_delete_notification">Benachrichtigung löschen</string>
<string name="sk_delete_notification_confirm_action">Benachrichtigung löschen</string>
<string name="sk_delete_notification_confirm">Benachrichtigung wirklich löschen\?</string>
<string name="sk_delete_notification_confirm">Benachrichtigung wirklich löschen?</string>
<string name="sk_clear_all_notifications">Alle Benachrichtigungen löschen</string>
<string name="sk_clear_all_notifications_confirm_action">Alle löschen</string>
<string name="sk_clear_all_notifications_confirm">Wirklich alle Benachrichtigungen löschen\?</string>
<string name="sk_clear_all_notifications_confirm">Wirklich alle Benachrichtigungen löschen?</string>
<string name="sk_enable_delete_notifications">Löschen von Benachrichtigungen aktivieren</string>
<string name="sk_settings_publish_button_text">Veröffentlichen-Button-Text</string>
<string name="sk_settings_publish_button_text_title">Veröffentlichen-Button-Text anpassen</string>
@@ -111,9 +111,9 @@
<string name="sk_draft">Entwurf</string>
<string name="sk_schedule">Planen</string>
<string name="sk_confirm_delete_draft_title">Entwurf löschen</string>
<string name="sk_confirm_delete_draft">Möchtest du diesen entworfenen Beitrag wirklich löschen\?</string>
<string name="sk_confirm_delete_draft">Möchtest du diesen entworfenen Beitrag wirklich löschen?</string>
<string name="sk_confirm_delete_scheduled_post_title">Geplanten Beitrag löschen</string>
<string name="sk_confirm_delete_scheduled_post">Möchtest du diesen geplanten Beitrag wirklich löschen\?</string>
<string name="sk_confirm_delete_scheduled_post">Möchtest du diesen geplanten Beitrag wirklich löschen?</string>
<string name="sk_draft_or_schedule">Entwurf oder Planen</string>
<string name="sk_compose_draft">Beitrag wird als Entwurf gespeichert.</string>
<string name="sk_compose_scheduled">Geplant für</string>
@@ -133,12 +133,5 @@
<string name="sk_no_image_desc_title">Keine Bildbeschreibung</string>
<string name="sk_no_image_desc">Die enthaltenen Bilder haben keine Beschreibung. Bitte füge eine Beschreibung hinzu, damit auch sehbehinderte Personen teilnehmen können.</string>
<string name="sk_emoji_recent">Kürzlich verwendet</string>
<string name="sk_clear_recent_emoji">Kürzlich verwendete Emojis löschen</string>
<string name="sk_disable_relocate_publish_button_to_enable_customization">Deaktiviere die Funktion "Veröffentlichen Schaltfläche verschieben", um eine Anpassung zu ermöglichen.</string>
<string name="sk_keep_only_latest_notification">Nur neueste Benachrichtigung behalten</string>
<string name="sk_announcements">Ankündigungen</string>
<string name="sk_mark_as_read">Als gelesen markieren</string>
<string name="sk_poll_option_add">Neue Umfrageoption hinzufügen</string>
<string name="sk_fab_compose">Verfassen</string>
<string name="sk_sending_error">Fehler beim Veröffentlichen</string>
</resources>
<string name="sk_clear_recent_emoji">Kürzlich verwendetes Emoji löschen</string>
</resources>

View File

@@ -37,7 +37,7 @@
<string name="sk_lists_with_user">Lists with %s</string>
<string name="sk_settings_always_reveal_content_warnings">Always reveal content warnings</string>
<string name="sk_disable_marquee">Disable scrolling text in title bars</string>
<string name="sk_disable_dividers">Disable post dividers</string>
<string name="sk_disable_dividers">Disable toot dividers</string>
<string name="sk_relocate_publish_button">Relocate publish button</string>
<string name="sk_settings_contribute">Contribute to Moshidon</string>
<string name="sk_settings_show_federated_timeline">Show federated timeline</string>
@@ -65,7 +65,7 @@
<string name="sk_welcome_title">Welcome!</string>
<string name="sk_welcome_text">The shark salutes you! To get started, please enter your home instances domain name below.</string>
<string name="sk_example_domain">example.social</string>
<string name="sk_app_username" translatable="false">\@moshidon</string>
<string name="sk_app_username" translatable="false">\@megalodon</string>
<string name="sk_tabs_disable_swipe">Disable swiping between tabs</string>
<string name="sk_settings_profile">Set up profile</string>
<string name="sk_settings_posting">Posting preferences</string>
@@ -135,14 +135,4 @@
<string name="sk_no_image_desc">The included images have no description. Please consider adding one, to allow visually impaired people to participate.</string>
<string name="sk_emoji_recent">Recently used</string>
<string name="sk_clear_recent_emoji">Clear recently used emoji</string>
<string name="sk_disable_relocate_publish_button_to_enable_customization">Disable "Relocate publish button" to allow customization</string>
<string name="sk_keep_only_latest_notification">Keep only latest notification</string>
<string name="sk_announcements">Announcements</string>
<string name="sk_mark_as_read">Mark as read</string>
<!-- accessibility labels-->
<string name="sk_poll_option_add">Add new poll option</string>
<string name="sk_fab_compose">Compose</string>
<string name="sk_sending_error">Error publishing</string>
</resources>

View File

@@ -381,7 +381,7 @@
<style name="Widget.Mastodon.M3.Button" parent="android:Widget.Material.Button">
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="android:textSize">14dp</item>
<item name="android:minHeight">40dp</item>
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:stateListAnimator">@null</item>
@@ -403,45 +403,45 @@
<style name="alert_title">
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:textSize">24sp</item>
<item name="android:textSize">24dp</item>
<item name="android:minHeight">38dp</item>
<item name="android:gravity">center_vertical</item>
</style>
<style name="m3_body_large">
<item name="android:textSize">16sp</item>
<item name="android:textSize">16dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:lineSpacingExtra">5dp</item>
</style>
<style name="m3_body_medium">
<item name="android:textSize">14sp</item>
<item name="android:textSize">14dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:lineSpacingExtra">4dp</item>
</style>
<style name="m3_body_small">
<item name="android:textSize">12sp</item>
<item name="android:textSize">12dp</item>
<item name="android:textColor">?android:textColorSecondary</item>
<item name="android:lineSpacingExtra">2dp</item>
</style>
<style name="m3_title_medium">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">16sp</item>
<item name="android:textSize">16dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:lineSpacingExtra">5dp</item>
</style>
<style name="m3_title_small">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">14sp</item>
<item name="android:textSize">14dp</item>
<item name="android:textColor">?android:textColorSecondary</item>
</style>
<style name="m3_label_medium">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">12sp</item>
<item name="android:textSize">12dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:lineSpacingMultiplier">1.14</item>
</style>
@@ -449,12 +449,12 @@
<style name="m3_label_large">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textColor">?android:textColorSecondary</item>
<item name="android:textSize">14sp</item>
<item name="android:textSize">14dp</item>
</style>
<style name="m3_title_large">
<item name="android:fontFamily">sans-serif-medium</item>
<item name="android:textSize">22sp</item>
<item name="android:textSize">22dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
@@ -465,12 +465,12 @@
</style>
<style name="m3_headline_small">
<item name="android:textSize">24sp</item>
<item name="android:textSize">24dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
<style name="m3_headline_medium">
<item name="android:textSize">28sp</item>
<item name="android:textSize">28dp</item>
<item name="android:textColor">?android:textColorPrimary</item>
<item name="android:lineSpacingExtra">3dp</item>
</style>

View File

@@ -1,7 +0,0 @@
New stuff that comes with Release 85:
Adding long click search button to bring up the keyboard
Clicking the search button when already in search tab also brings up keyboard
Bringing up a bot icon to toots from bot accounts, Thanks @FineFindus!
Improving visibility of bot icon inside account profile, Thanks @FineFindus!
Updating german translation, Thanks @Dontobi!
Fixing minor UI issues

View File

@@ -1,4 +0,0 @@
New things for release 86:
- Ability to stack notifications, ie: having multiple notifications;
- Introducing Announcements;
- Many minor UI fixes.