mirror of
https://codeberg.org/tom79/Fedilab.git
synced 2025-01-07 00:20:08 +02:00
Merge branch 'develop' into main
This commit is contained in:
commit
83ad77f3ea
32 changed files with 978 additions and 175 deletions
|
@ -9,8 +9,8 @@ android {
|
|||
defaultConfig {
|
||||
minSdk 21
|
||||
targetSdk 31
|
||||
versionCode 399
|
||||
versionName "3.0.9"
|
||||
versionCode 400
|
||||
versionName "3.0.10"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
flavorDimensions "default"
|
||||
|
|
52
app/src/main/assets/release_notes/notes.json
Normal file
52
app/src/main/assets/release_notes/notes.json
Normal file
|
@ -0,0 +1,52 @@
|
|||
[
|
||||
{
|
||||
"version": "3.0.10",
|
||||
"code": "400",
|
||||
"note": "Added:\n- Allow to define the max chars count when not detected (In about the instance)\n- Add emoji one picker when composing (must be enabled in settings)\n- Add release notes with the ability to translate them\n\nFixed:\n- Friendica custom emojis not displayed\n- Long press to store media\n- Some bug fixes"
|
||||
},
|
||||
{
|
||||
"version": "3.0.9",
|
||||
"code": "399",
|
||||
"note": "Added:\n- Set compose language (from compose menu -> three vertical dots)\n- Add reactions support for Pleroma\n- Add privacy indicator at the top right\n\nChanged\n- Improve the scrolling behaviour\n- Scroll to top (tab reselection) will fetch new messages and then scroll to top\n\nFixed:\n- Empty tag timelines\n- Remove focus point for fit media preview\n- Fix cannot share with one account\n- Fix black theme\n- Theme cannot be selected\n- Fix some button colors"
|
||||
},
|
||||
{
|
||||
"version": "3.0.8",
|
||||
"code": "398",
|
||||
"note": "- Keep improving the scroll behaviour\n- Scroll to top (tab reselection) will fetch new messages and then scroll to top\n- Remove focus point for fit media preview\n- Fix cannot share with one account\n- Fix black theme\n- Fix some button colors"
|
||||
},
|
||||
{
|
||||
"version": "3.0.7",
|
||||
"code": "397",
|
||||
"note": "- Fix some bugs reported."
|
||||
},
|
||||
{
|
||||
"version": "3.0.6",
|
||||
"code": "396",
|
||||
"note": "Added:\n- Allow to set a focus point on previews (media editor)\n- Respect the focus point with previews\n- Pagination with the fetch more button support reading up or down\n- Add trends\n\nFixed:\n- Only last push notification is displayed (not grouped)\n- Bad behavior with the right/left scroll\n- Fix long profiles not fully displayed\n- Issues with some polls\n- Some crashes\n- Some bad behaviors"
|
||||
},
|
||||
{
|
||||
"version": "3.0.5",
|
||||
"code": "395",
|
||||
"note": "- Fix some bugs\n- Allow to share with the app"
|
||||
},
|
||||
{
|
||||
"version": "3.0.4",
|
||||
"code": "394",
|
||||
"note": "- Fix crashes for some Pleroma instances"
|
||||
},
|
||||
{
|
||||
"version": "3.0.2",
|
||||
"code": "393",
|
||||
"note": "- Some bug fixes\n- Improve pinned timelines"
|
||||
},
|
||||
{
|
||||
"version": "3.0.1",
|
||||
"code": "391",
|
||||
"note": "Some quick fixes"
|
||||
},
|
||||
{
|
||||
"version": "3.0.0",
|
||||
"code": "390",
|
||||
"note": "New version of Fedilab with new feature.\n- You can now compose threads\n- See the whole thread when replying\n- Cache support\n- New design"
|
||||
}
|
||||
]
|
|
@ -18,6 +18,7 @@ import static app.fedilab.android.BaseMainActivity.status.DISCONNECTED;
|
|||
import static app.fedilab.android.BaseMainActivity.status.UNKNOWN;
|
||||
import static app.fedilab.android.helper.CacheHelper.deleteDir;
|
||||
import static app.fedilab.android.helper.Helper.PREF_USER_TOKEN;
|
||||
import static app.fedilab.android.helper.Helper.displayReleaseNotesIfNeeded;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.BroadcastReceiver;
|
||||
|
@ -504,6 +505,8 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
} else if (id == R.id.nav_about) {
|
||||
Intent intent = new Intent(this, AboutActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_release_notes) {
|
||||
displayReleaseNotesIfNeeded(BaseMainActivity.this, true);
|
||||
} else if (id == R.id.nav_partnership) {
|
||||
Intent intent = new Intent(this, PartnerShipActivity.class);
|
||||
startActivity(intent);
|
||||
|
@ -516,10 +519,15 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
} else if (id == R.id.nav_cache) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, CacheActivity.class);
|
||||
startActivity(intent);
|
||||
} else if (id == R.id.nav_about_instance) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, InstanceActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
binding.drawerLayout.close();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
headerMainBinding.instanceInfo.setOnClickListener(v -> startActivity(new Intent(BaseMainActivity.this, InstanceHealthActivity.class)));
|
||||
headerMainBinding.accountProfilePicture.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(BaseMainActivity.this, ProfileActivity.class);
|
||||
|
@ -677,10 +685,6 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
AlertDialog alert = alt_bld.create();
|
||||
alert.show();
|
||||
return true;
|
||||
} else if (itemId == R.id.action_about_instance) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, InstanceActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
} else if (itemId == R.id.action_proxy) {
|
||||
Intent intent = new Intent(BaseMainActivity.this, ProxyActivity.class);
|
||||
startActivity(intent);
|
||||
|
@ -759,6 +763,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
|
||||
currentInstance = currentAccount.instance;
|
||||
currentUserID = currentAccount.user_id;
|
||||
|
||||
show_boosts = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_BOOSTS) + currentUserID + currentInstance, true);
|
||||
show_replies = sharedpreferences.getBoolean(getString(R.string.SET_SHOW_REPLIES) + currentUserID + currentInstance, true);
|
||||
regex_home = sharedpreferences.getString(getString(R.string.SET_FILTER_REGEX_HOME) + currentUserID + currentInstance, null);
|
||||
|
@ -799,6 +804,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
.observe(BaseMainActivity.this, mastodonAccount -> {
|
||||
//Initialize static var
|
||||
currentAccount.mastodon_account = mastodonAccount;
|
||||
displayReleaseNotesIfNeeded(BaseMainActivity.this, false);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
//Update account in db
|
||||
|
|
|
@ -53,14 +53,12 @@ public class ContextActivity extends BaseActivity {
|
|||
public static boolean displayCW;
|
||||
public static Resources.Theme theme;
|
||||
Fragment currentFragment;
|
||||
private Status focusedStatus;
|
||||
private ActivityConversationBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeHelper.applyTheme(this);
|
||||
binding = ActivityConversationBinding.inflate(getLayoutInflater());
|
||||
app.fedilab.android.databinding.ActivityConversationBinding binding = ActivityConversationBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setSupportActionBar(binding.toolbar);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
|
@ -78,7 +76,7 @@ public class ContextActivity extends BaseActivity {
|
|||
Bundle b = getIntent().getExtras();
|
||||
final SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(ContextActivity.this);
|
||||
displayCW = sharedpreferences.getBoolean(getString(R.string.SET_EXPAND_CW), false);
|
||||
focusedStatus = null; // or other values
|
||||
Status focusedStatus = null; // or other values
|
||||
if (b != null)
|
||||
focusedStatus = (Status) b.getSerializable(Helper.ARG_STATUS);
|
||||
if (focusedStatus == null || currentAccount == null || currentAccount.mastodon_account == null) {
|
||||
|
|
|
@ -16,6 +16,8 @@ package app.fedilab.android.activities;
|
|||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
|
@ -23,11 +25,15 @@ import android.text.Html;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
|
@ -35,13 +41,13 @@ import app.fedilab.android.client.entities.api.Instance;
|
|||
import app.fedilab.android.databinding.ActivityInstanceBinding;
|
||||
import app.fedilab.android.helper.ThemeHelper;
|
||||
import app.fedilab.android.viewmodel.mastodon.InstancesVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
||||
public class InstanceActivity extends BaseActivity {
|
||||
|
||||
|
||||
ActivityInstanceBinding binding;
|
||||
private boolean applyMaxChar = false;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -54,8 +60,26 @@ public class InstanceActivity extends BaseActivity {
|
|||
getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().hide();
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(InstanceActivity.this);
|
||||
binding.close.setOnClickListener(
|
||||
|
||||
binding.close.setOnClickListener(view -> finish());
|
||||
view -> {
|
||||
if (applyMaxChar) {
|
||||
String max_char = binding.maxChar.getText().toString();
|
||||
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
if (!max_char.isEmpty()) {
|
||||
try {
|
||||
editor.putInt(getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, Integer.parseInt(max_char));
|
||||
editor.apply();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
@ -66,33 +90,53 @@ public class InstanceActivity extends BaseActivity {
|
|||
instancesVM.getInstance(BaseMainActivity.currentInstance).observe(InstanceActivity.this, instanceInfo -> {
|
||||
binding.instanceContainer.setVisibility(View.VISIBLE);
|
||||
binding.loader.setVisibility(View.GONE);
|
||||
if (instanceInfo == null || instanceInfo.info == null) {
|
||||
Toasty.error(InstanceActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
Instance instance = instanceInfo.info;
|
||||
binding.instanceTitle.setText(instance.title);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
binding.instanceDescription.setText(Html.fromHtml(instance.description, Html.FROM_HTML_MODE_LEGACY));
|
||||
else
|
||||
binding.instanceDescription.setText(Html.fromHtml(instance.description));
|
||||
if (instance.description == null || instance.description.trim().length() == 0)
|
||||
binding.instanceDescription.setText(getString(R.string.instance_no_description));
|
||||
binding.instanceVersion.setText(instance.version);
|
||||
binding.instanceUri.setText(instance.uri);
|
||||
if (instance.email == null) {
|
||||
binding.instanceContact.hide();
|
||||
}
|
||||
Glide.with(InstanceActivity.this)
|
||||
.asBitmap()
|
||||
.load(instance.thumbnail)
|
||||
.into(binding.backGroundImage);
|
||||
|
||||
binding.instanceContact.setOnClickListener(v -> {
|
||||
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", instance.email, null));
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "[Mastodon] - " + instance.uri);
|
||||
startActivity(Intent.createChooser(emailIntent, getString(R.string.send_email)));
|
||||
});
|
||||
if (instanceInfo == null || instanceInfo.info == null || instanceInfo.info.description == null) {
|
||||
binding.maxCharContainer.setVisibility(View.VISIBLE);
|
||||
binding.instanceContainer.setVisibility(View.GONE);
|
||||
binding.instanceContact.setVisibility(View.GONE);
|
||||
int val = sharedpreferences.getInt(getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, -1);
|
||||
if (val != -1) {
|
||||
binding.maxChar.setText(String.valueOf(val));
|
||||
}
|
||||
applyMaxChar = true;
|
||||
|
||||
} else {
|
||||
Instance instance = instanceInfo.info;
|
||||
binding.instanceTitle.setText(instance.title);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
binding.instanceDescription.setText(Html.fromHtml(instance.description, Html.FROM_HTML_MODE_LEGACY));
|
||||
else
|
||||
binding.instanceDescription.setText(Html.fromHtml(instance.description));
|
||||
if (instance.description == null || instance.description.trim().length() == 0)
|
||||
binding.instanceDescription.setText(getString(R.string.instance_no_description));
|
||||
binding.instanceVersion.setText(instance.version);
|
||||
binding.instanceUri.setText(instance.uri);
|
||||
if (instance.email == null) {
|
||||
binding.instanceContact.hide();
|
||||
}
|
||||
Glide.with(InstanceActivity.this)
|
||||
.asDrawable()
|
||||
.load(instance.thumbnail)
|
||||
.into(new CustomTarget<Drawable>() {
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
|
||||
binding.background.setAlpha(0.2f);
|
||||
binding.background.setBackground(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
binding.instanceContact.setOnClickListener(v -> {
|
||||
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", instance.email, null));
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "[Mastodon] - " + instance.uri);
|
||||
startActivity(Intent.createChooser(emailIntent, getString(R.string.send_email)));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,11 @@ public class Account implements Serializable {
|
|||
if (display_name == null || display_name.isEmpty()) {
|
||||
display_name = username;
|
||||
}
|
||||
return SpannableHelper.convert(context, display_name, null, this, null, true, viewWeakReference);
|
||||
return SpannableHelper.convert(context, display_name, null, this, null, false, viewWeakReference);
|
||||
}
|
||||
|
||||
public synchronized Spannable getSpanDisplayNameTitle(Context context, WeakReference<View> viewWeakReference, String title) {
|
||||
return SpannableHelper.convert(context, title, null, this, null, false, viewWeakReference);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ public class Poll implements Serializable {
|
|||
public transient Spannable span_title;
|
||||
|
||||
public Spannable getSpanTitle(Context context, Status status, WeakReference<View> viewWeakReference) {
|
||||
span_title = SpannableHelper.convert(context, title, status, null, null, true, viewWeakReference);
|
||||
span_title = SpannableHelper.convert(context, title, status, null, null, false, viewWeakReference);
|
||||
return span_title;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package app.fedilab.android.client.entities.app;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ReleaseNote implements Serializable {
|
||||
|
||||
@SerializedName("languages")
|
||||
public List<Note> ReleaseNotes;
|
||||
|
||||
|
||||
public static class Note implements Serializable {
|
||||
@SerializedName("code")
|
||||
public String code;
|
||||
@SerializedName("version")
|
||||
public String version;
|
||||
@SerializedName("note")
|
||||
public String note;
|
||||
@SerializedName("noteTranslated")
|
||||
public String noteTranslated;
|
||||
}
|
||||
}
|
|
@ -74,6 +74,7 @@ import androidx.annotation.IdRes;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.app.ActivityOptionsCompat;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
@ -81,10 +82,12 @@ import androidx.core.graphics.drawable.DrawableCompat;
|
|||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.lifecycle.ViewModelStoreOwner;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
|
@ -95,6 +98,7 @@ import com.bumptech.glide.request.RequestOptions;
|
|||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
@ -115,10 +119,12 @@ import java.net.InetSocketAddress;
|
|||
import java.net.PasswordAuthentication;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Security;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -133,19 +139,26 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.BuildConfig;
|
||||
import app.fedilab.android.MainApplication;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.ComposeActivity;
|
||||
import app.fedilab.android.activities.LoginActivity;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.activities.ProfileActivity;
|
||||
import app.fedilab.android.activities.WebviewActivity;
|
||||
import app.fedilab.android.broadcastreceiver.ToastMessage;
|
||||
import app.fedilab.android.client.entities.api.Attachment;
|
||||
import app.fedilab.android.client.entities.api.Status;
|
||||
import app.fedilab.android.client.entities.app.Account;
|
||||
import app.fedilab.android.client.entities.app.BaseAccount;
|
||||
import app.fedilab.android.client.entities.app.ReleaseNote;
|
||||
import app.fedilab.android.databinding.PopupReleaseNotesBinding;
|
||||
import app.fedilab.android.exception.DBException;
|
||||
import app.fedilab.android.interfaces.OnDownloadInterface;
|
||||
import app.fedilab.android.sqlite.Sqlite;
|
||||
import app.fedilab.android.ui.drawer.ReleaseNoteAdapter;
|
||||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.OauthVM;
|
||||
import app.fedilab.android.watermark.androidwm.WatermarkBuilder;
|
||||
import app.fedilab.android.watermark.androidwm.bean.WatermarkText;
|
||||
|
@ -1461,11 +1474,11 @@ public class Helper {
|
|||
}
|
||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId)
|
||||
.setSmallIcon(R.drawable.ic_notification).setTicker(message);
|
||||
if (notifType == NotifType.MENTION) {
|
||||
/* if (notifType == NotifType.MENTION) {
|
||||
if (message.length() > 500) {
|
||||
message = message.substring(0, 499) + "…";
|
||||
}
|
||||
}
|
||||
}*/
|
||||
notificationBuilder.setGroup(account.mastodon_account.acct + "@" + account.instance)
|
||||
.setContentIntent(pIntent)
|
||||
.setContentText(message);
|
||||
|
@ -1748,4 +1761,112 @@ public class Helper {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void displayReleaseNotesIfNeeded(Activity activity, boolean forced) {
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
|
||||
int lastReleaseNoteRead = sharedpreferences.getInt(activity.getString(R.string.SET_POPUP_RELEASE_NOTES), 0);
|
||||
int versionCode = BuildConfig.VERSION_CODE;
|
||||
if (lastReleaseNoteRead != versionCode || forced) {
|
||||
try {
|
||||
InputStream is = activity.getAssets().open("release_notes/notes.json");
|
||||
int size;
|
||||
size = is.available();
|
||||
byte[] buffer = new byte[size];
|
||||
is.read(buffer);
|
||||
is.close();
|
||||
String json = new String(buffer, StandardCharsets.UTF_8);
|
||||
Gson gson = new Gson();
|
||||
AlertDialog.Builder dialogBuilderOptin = new AlertDialog.Builder(activity, Helper.dialogStyle());
|
||||
PopupReleaseNotesBinding binding = PopupReleaseNotesBinding.inflate(activity.getLayoutInflater());
|
||||
dialogBuilderOptin.setView(binding.getRoot());
|
||||
try {
|
||||
List<ReleaseNote.Note> releaseNotes = gson.fromJson(json, new TypeToken<List<ReleaseNote.Note>>() {
|
||||
}.getType());
|
||||
if (releaseNotes != null && releaseNotes.size() > 0) {
|
||||
ReleaseNoteAdapter adapter = new ReleaseNoteAdapter(releaseNotes);
|
||||
binding.releasenotes.setAdapter(adapter);
|
||||
binding.releasenotes.setLayoutManager(new LinearLayoutManager(activity));
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
if (BuildConfig.DONATIONS) {
|
||||
binding.aboutSupport.setVisibility(View.VISIBLE);
|
||||
binding.aboutSupportPaypal.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
binding.aboutSupport.setVisibility(View.GONE);
|
||||
binding.aboutSupportPaypal.setVisibility(View.GONE);
|
||||
}
|
||||
binding.accountFollow.setBackgroundTintList(ThemeHelper.getButtonActionColorStateList(activity));
|
||||
binding.accountFollow.setImageResource(R.drawable.ic_baseline_person_add_24);
|
||||
binding.aboutSupport.setOnClickListener(v -> {
|
||||
Intent intentLiberapay = new Intent(Intent.ACTION_VIEW);
|
||||
intentLiberapay.setData(Uri.parse("https://liberapay.com/tom79"));
|
||||
try {
|
||||
activity.startActivity(intentLiberapay);
|
||||
} catch (Exception e) {
|
||||
Helper.openBrowser(activity, "https://liberapay.com/tom79");
|
||||
}
|
||||
});
|
||||
binding.aboutSupportPaypal.setOnClickListener(v -> Helper.openBrowser(activity, "https://www.paypal.me/Mastalab"));
|
||||
CrossActionHelper.fetchRemoteAccount(activity, "@apps@toot.fedilab.app", new CrossActionHelper.Callback() {
|
||||
@Override
|
||||
public void federatedStatus(Status status) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void federatedAccount(app.fedilab.android.client.entities.api.Account account) {
|
||||
if (account != null && account.username.equalsIgnoreCase("apps")) {
|
||||
|
||||
MastodonHelper.loadPPMastodon(binding.accountPp, account);
|
||||
binding.accountDn.setText(account.display_name);
|
||||
binding.accountUn.setText(account.acct);
|
||||
binding.accountPp.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(activity, ProfileActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putSerializable(Helper.ARG_ACCOUNT, account);
|
||||
intent.putExtras(b);
|
||||
ActivityOptionsCompat options = ActivityOptionsCompat
|
||||
.makeSceneTransitionAnimation(activity, binding.accountPp, activity.getString(R.string.activity_porfile_pp));
|
||||
activity.startActivity(intent, options.toBundle());
|
||||
});
|
||||
|
||||
AccountsVM accountsVM = new ViewModelProvider((ViewModelStoreOwner) activity).get(AccountsVM.class);
|
||||
List<String> ids = new ArrayList<>();
|
||||
ids.add(account.id);
|
||||
accountsVM.getRelationships(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, ids)
|
||||
.observe((LifecycleOwner) activity, relationShips -> {
|
||||
if (relationShips != null && relationShips.size() > 0) {
|
||||
if (!relationShips.get(0).following) {
|
||||
binding.acccountContainer.setVisibility(View.VISIBLE);
|
||||
binding.accountFollow.setVisibility(View.VISIBLE);
|
||||
binding.accountFollow.setOnClickListener(v -> accountsVM.follow(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, account.id, true, false)
|
||||
.observe((LifecycleOwner) activity, relationShip -> binding.accountFollow.setVisibility(View.GONE)));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
dialogBuilderOptin.setPositiveButton(R.string.close, (dialog, id) -> dialog.dismiss());
|
||||
try {
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(() -> {
|
||||
if (!activity.isFinishing()) {
|
||||
dialogBuilderOptin.show();
|
||||
}
|
||||
}, 1000);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
editor.putInt(activity.getString(R.string.SET_POPUP_RELEASE_NOTES), versionCode);
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ package app.fedilab.android.helper;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import static app.fedilab.android.BaseMainActivity.instanceInfo;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -51,6 +53,7 @@ import java.util.regex.Pattern;
|
|||
|
||||
import app.fedilab.android.BaseMainActivity;
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.client.entities.api.Account;
|
||||
import app.fedilab.android.client.entities.api.Pagination;
|
||||
import app.fedilab.android.client.entities.api.RelationShip;
|
||||
|
@ -499,4 +502,19 @@ public class MastodonHelper {
|
|||
void onTimedMute(RelationShip relationShip);
|
||||
}
|
||||
|
||||
public static int getInstanceMaxChars(Context context) {
|
||||
int max_car;
|
||||
if (instanceInfo != null) {
|
||||
max_car = instanceInfo.max_toot_chars != null ? Integer.parseInt(instanceInfo.max_toot_chars) : instanceInfo.configuration.statusesConf.max_characters;
|
||||
} else {
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
int val = sharedpreferences.getInt(context.getString(R.string.SET_MAX_INSTANCE_CHAR) + MainActivity.currentInstance, -1);
|
||||
if (val != -1) {
|
||||
return val;
|
||||
} else {
|
||||
max_car = 500;
|
||||
}
|
||||
}
|
||||
return max_car;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
@ -89,6 +90,17 @@ public class SpannableHelper {
|
|||
if (text == null) {
|
||||
return null;
|
||||
}
|
||||
Pattern imgPattern = Pattern.compile("<img [^>]*src=\"([^\"]+)\"[^>]*>");
|
||||
Matcher matcherImg = imgPattern.matcher(text);
|
||||
HashMap<String, String> imagesToReplace = new LinkedHashMap<>();
|
||||
int inc = 0;
|
||||
while (matcherImg.find()) {
|
||||
String replacement = "[FEDI_IMG_" + inc + "]";
|
||||
imagesToReplace.put(replacement, matcherImg.group(1));
|
||||
inc++;
|
||||
text = text.replaceAll(Pattern.quote(matcherImg.group()), replacement);
|
||||
}
|
||||
|
||||
SpannableStringBuilder content;
|
||||
View view = viewWeakReference.get();
|
||||
List<Mention> mentionList = null;
|
||||
|
@ -132,9 +144,9 @@ public class SpannableHelper {
|
|||
} else {
|
||||
content = new SpannableStringBuilder(text);
|
||||
}
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
|
||||
if (emojiList != null && emojiList.size() > 0) {
|
||||
SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean animate = !sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_ANIMATED_EMOJI), false);
|
||||
for (Emoji emoji : emojiList) {
|
||||
Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL)
|
||||
.matcher(content);
|
||||
|
@ -148,6 +160,24 @@ public class SpannableHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imagesToReplace.size() > 0) {
|
||||
for (Map.Entry<String, String> entry : imagesToReplace.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String url = entry.getValue();
|
||||
Matcher matcher = Pattern.compile(key, Pattern.LITERAL)
|
||||
.matcher(content);
|
||||
while (matcher.find()) {
|
||||
CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(view));
|
||||
content.setSpan(customEmoji, matcher.start(), matcher.end(), 0);
|
||||
Glide.with(view)
|
||||
.asDrawable()
|
||||
.load(url)
|
||||
.into(customEmoji.getTarget(animate));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return trimSpannable(new SpannableStringBuilder(content));
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ package app.fedilab.android.ui.drawer;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||
import static app.fedilab.android.BaseMainActivity.currentAccount;
|
||||
import static app.fedilab.android.BaseMainActivity.emojis;
|
||||
import static app.fedilab.android.BaseMainActivity.instanceInfo;
|
||||
|
@ -45,6 +46,7 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.GridView;
|
||||
|
@ -71,6 +73,9 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
|||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.CustomTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.vanniktech.emoji.EmojiManager;
|
||||
import com.vanniktech.emoji.EmojiPopup;
|
||||
import com.vanniktech.emoji.one.EmojiOneProvider;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
@ -712,12 +717,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
public void afterTextChanged(Editable s) {
|
||||
int currentLength = MastodonHelper.countLength(holder);
|
||||
//Copy/past
|
||||
int max_car;
|
||||
if (instanceInfo != null) {
|
||||
max_car = instanceInfo.max_toot_chars != null ? Integer.parseInt(instanceInfo.max_toot_chars) : instanceInfo.configuration.statusesConf.max_characters;
|
||||
} else {
|
||||
max_car = 500;
|
||||
}
|
||||
int max_car = MastodonHelper.getInstanceMaxChars(context);
|
||||
if (currentLength > max_car + 1) {
|
||||
int from = max_car - holder.binding.contentSpoiler.getText().length();
|
||||
int to = (currentLength - holder.binding.contentSpoiler.getText().length());
|
||||
|
@ -1078,6 +1078,22 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
|
||||
ComposeViewHolder holder = (ComposeViewHolder) viewHolder;
|
||||
|
||||
boolean displayEmoji = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_EMOJI), false);
|
||||
if (displayEmoji) {
|
||||
holder.binding.buttonEmojiOne.setVisibility(View.VISIBLE);
|
||||
holder.binding.buttonEmojiOne.setOnClickListener(v -> {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(holder.binding.buttonEmojiOne.getWindowToken(), 0);
|
||||
EmojiManager.install(new EmojiOneProvider());
|
||||
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(holder.binding.buttonEmojiOne).setOnEmojiPopupDismissListener(() -> {
|
||||
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
|
||||
}).build(holder.binding.content);
|
||||
emojiPopup.toggle();
|
||||
});
|
||||
} else {
|
||||
holder.binding.buttonEmojiOne.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
int newInputType = holder.binding.content.getInputType() & (holder.binding.content.getInputType() ^ InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
|
||||
holder.binding.content.setInputType(newInputType);
|
||||
|
||||
|
@ -1246,7 +1262,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||
if (instanceInfo == null) {
|
||||
return;
|
||||
}
|
||||
int max_car = instanceInfo.max_toot_chars != null ? Integer.parseInt(instanceInfo.max_toot_chars) : instanceInfo.configuration.statusesConf.max_characters;
|
||||
int max_car = MastodonHelper.getInstanceMaxChars(context);
|
||||
holder.binding.characterProgress.setMax(max_car);
|
||||
holder.binding.contentSpoiler.addTextChangedListener(new TextWatcher() {
|
||||
private int cPosition;
|
||||
|
|
|
@ -224,10 +224,9 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
title = String.format(Locale.getDefault(), "%s reacted with %s", notification.account.username, notification.emoji);
|
||||
MastodonHelper.loadPPMastodon(holderStatus.bindingNotification.status.avatar, notification.account);
|
||||
}
|
||||
notification.account.display_name = title;
|
||||
holderStatus.bindingNotification.status.displayName.setText(
|
||||
notification.account.getSpanDisplayName(context,
|
||||
new WeakReference<>(holderStatus.bindingNotification.status.displayName)),
|
||||
notification.account.getSpanDisplayNameTitle(context,
|
||||
new WeakReference<>(holderStatus.bindingNotification.status.displayName), title),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
holderStatus.bindingNotification.status.username.setText(String.format("@%s", notification.account.acct));
|
||||
holderStatus.bindingNotification.containerTransparent.setAlpha(.1f);
|
||||
|
@ -295,10 +294,10 @@ public class NotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
|
|||
// start the new activity
|
||||
context.startActivity(intent, options.toBundle());
|
||||
});
|
||||
notification.account.display_name = title;
|
||||
|
||||
holderStatus.bindingNotification.status.displayName.setText(
|
||||
notification.account.getSpanDisplayName(context,
|
||||
new WeakReference<>(holderStatus.bindingNotification.status.displayName)),
|
||||
notification.account.getSpanDisplayNameTitle(context,
|
||||
new WeakReference<>(holderStatus.bindingNotification.status.displayName), title),
|
||||
TextView.BufferType.SPANNABLE);
|
||||
holderStatus.bindingNotification.status.displayName.setText(title, TextView.BufferType.SPANNABLE);
|
||||
holderStatus.bindingNotification.status.username.setText(String.format("@%s", notification.account.acct));
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package app.fedilab.android.ui.drawer;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.github.stom79.mytransl.MyTransL;
|
||||
import com.github.stom79.mytransl.client.HttpsConnectionException;
|
||||
import com.github.stom79.mytransl.client.Results;
|
||||
import com.github.stom79.mytransl.translate.Params;
|
||||
import com.github.stom79.mytransl.translate.Translate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import app.fedilab.android.R;
|
||||
import app.fedilab.android.client.entities.app.ReleaseNote;
|
||||
import app.fedilab.android.databinding.DrawerReleaseNoteBinding;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
||||
public class ReleaseNoteAdapter extends RecyclerView.Adapter<ReleaseNoteAdapter.ReleaseNoteViewHolder> {
|
||||
|
||||
private final List<ReleaseNote.Note> notes;
|
||||
private Context context;
|
||||
|
||||
public ReleaseNoteAdapter(List<ReleaseNote.Note> notes) {
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return notes.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReleaseNoteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
context = parent.getContext();
|
||||
DrawerReleaseNoteBinding itemBinding = DrawerReleaseNoteBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
|
||||
return new ReleaseNoteViewHolder(itemBinding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ReleaseNoteViewHolder holder, int position) {
|
||||
ReleaseNote.Note note = notes.get(position);
|
||||
holder.binding.note.setText(note.note);
|
||||
holder.binding.version.setText(String.format(Locale.getDefault(), "%s (%s)", note.version, note.code));
|
||||
if (note.noteTranslated != null) {
|
||||
holder.binding.noteTranslated.setText(note.noteTranslated);
|
||||
holder.binding.containerTrans.setVisibility(View.VISIBLE);
|
||||
holder.binding.translate.setVisibility(View.GONE);
|
||||
} else {
|
||||
holder.binding.containerTrans.setVisibility(View.GONE);
|
||||
holder.binding.translate.setVisibility(View.VISIBLE);
|
||||
}
|
||||
holder.binding.translate.setOnClickListener(v -> {
|
||||
MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE;
|
||||
final MyTransL myTransL = MyTransL.getInstance(et);
|
||||
myTransL.setObfuscation(true);
|
||||
Params params = new Params();
|
||||
params.setSplit_sentences(false);
|
||||
params.setFormat(Params.fType.TEXT);
|
||||
params.setSource_lang("auto");
|
||||
myTransL.setLibretranslateDomain("translate.fedilab.app");
|
||||
myTransL.translate(note.note, MyTransL.getLocale(), params, new Results() {
|
||||
@Override
|
||||
public void onSuccess(Translate translate) {
|
||||
if (translate.getTranslatedContent() != null) {
|
||||
note.noteTranslated = translate.getTranslatedContent();
|
||||
notifyItemChanged(holder.getBindingAdapterPosition());
|
||||
} else {
|
||||
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFail(HttpsConnectionException httpsConnectionException) {
|
||||
Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static class ReleaseNoteViewHolder extends RecyclerView.ViewHolder {
|
||||
DrawerReleaseNoteBinding binding;
|
||||
|
||||
ReleaseNoteViewHolder(DrawerReleaseNoteBinding itemView) {
|
||||
super(itemView.getRoot());
|
||||
binding = itemView;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -75,7 +75,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.RequestBuilder;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.github.stom79.mytransl.MyTransL;
|
||||
|
@ -129,6 +128,7 @@ import app.fedilab.android.helper.GlideFocus;
|
|||
import app.fedilab.android.helper.Helper;
|
||||
import app.fedilab.android.helper.LongClickLinkMovementMethod;
|
||||
import app.fedilab.android.helper.MastodonHelper;
|
||||
import app.fedilab.android.helper.MediaHelper;
|
||||
import app.fedilab.android.helper.SpannableHelper;
|
||||
import app.fedilab.android.helper.ThemeHelper;
|
||||
import app.fedilab.android.ui.fragment.timeline.FragmentMastodonContext;
|
||||
|
@ -324,6 +324,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
boolean confirmBoost = sharedpreferences.getBoolean(context.getString(R.string.SET_NOTIF_VALIDATION), true);
|
||||
boolean fullAttachement = sharedpreferences.getBoolean(context.getString(R.string.SET_FULL_PREVIEW), false);
|
||||
boolean displayBookmark = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_BOOKMARK), false);
|
||||
boolean long_press_media = sharedpreferences.getBoolean(context.getString(R.string.SET_LONG_PRESS_STORE_MEDIA), false);
|
||||
|
||||
if (MainActivity.currentAccount != null && MainActivity.currentAccount.api == Account.API.PLEROMA) {
|
||||
holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE);
|
||||
|
@ -344,6 +345,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
}).setOnEmojiClickListener((emoji, imageView) -> {
|
||||
String emojiStr = imageView.getUnicode();
|
||||
boolean alreadyAdded = false;
|
||||
if (status.pleroma == null || status.pleroma.emoji_reactions == null) {
|
||||
return;
|
||||
}
|
||||
for (Reaction reaction : status.pleroma.emoji_reactions) {
|
||||
if (reaction.name.compareTo(emojiStr) == 0) {
|
||||
alreadyAdded = true;
|
||||
|
@ -386,12 +390,14 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
GridView gridView = new GridView(context);
|
||||
gridView.setAdapter(new EmojiAdapter(emojis.get(BaseMainActivity.currentInstance)));
|
||||
gridView.setNumColumns(5);
|
||||
AlertDialog finalAlertDialogEmoji = alertDialogEmoji;
|
||||
gridView.setOnItemClickListener((parent, view, index, id) -> {
|
||||
String emojiStr = emojis.get(BaseMainActivity.currentInstance).get(index).shortcode;
|
||||
String url = emojis.get(BaseMainActivity.currentInstance).get(index).url;
|
||||
String static_url = emojis.get(BaseMainActivity.currentInstance).get(index).static_url;
|
||||
boolean alreadyAdded = false;
|
||||
if (status.pleroma == null || status.pleroma.emoji_reactions == null) {
|
||||
return;
|
||||
}
|
||||
for (Reaction reaction : status.pleroma.emoji_reactions) {
|
||||
if (reaction.name.compareTo(emojiStr) == 0) {
|
||||
alreadyAdded = true;
|
||||
|
@ -419,9 +425,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
} else {
|
||||
actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
|
||||
}
|
||||
if (finalAlertDialogEmoji != null) {
|
||||
finalAlertDialogEmoji.dismiss();
|
||||
}
|
||||
});
|
||||
gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
||||
builder.setView(gridView);
|
||||
|
@ -431,7 +434,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
textView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
||||
builder.setView(textView);
|
||||
}
|
||||
alertDialogEmoji = builder.show();
|
||||
builder.show();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -892,7 +895,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
holder.binding.username.setCompoundDrawables(null, null, null, null);
|
||||
}
|
||||
|
||||
|
||||
if (statusToDeal.account.bot) {
|
||||
holder.binding.botIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.binding.botIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
@ -1121,6 +1126,19 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
} else {
|
||||
layoutMediaBinding.playMusic.setVisibility(View.GONE);
|
||||
}
|
||||
String finalUrl;
|
||||
if (statusToDeal.media_attachments.get(0).url == null) {
|
||||
finalUrl = statusToDeal.media_attachments.get(0).remote_url;
|
||||
} else {
|
||||
finalUrl = statusToDeal.media_attachments.get(0).url;
|
||||
}
|
||||
layoutMediaBinding.media.setOnLongClickListener(v -> {
|
||||
if (long_press_media) {
|
||||
MediaHelper.manageMove(context, finalUrl, false);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
float focusX = 0.f;
|
||||
float focusY = 0.f;
|
||||
if (statusToDeal.media_attachments.get(0).meta != null && statusToDeal.media_attachments.get(0).meta.focus != null) {
|
||||
|
@ -1131,8 +1149,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
if (!mediaObfuscated(statusToDeal) || expand_media) {
|
||||
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24);
|
||||
RequestBuilder<Drawable> requestBuilder = Glide.with(layoutMediaBinding.media.getContext())
|
||||
.load(statusToDeal.media_attachments.get(0).preview_url)
|
||||
.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
|
||||
.load(statusToDeal.media_attachments.get(0).preview_url);
|
||||
if (!fullAttachement) {
|
||||
requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
|
||||
}
|
||||
|
@ -1164,6 +1181,18 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
focusY = statusToDeal.media_attachments.get(0).meta.focus.y;
|
||||
}
|
||||
|
||||
String finalUrl;
|
||||
if (attachment.url == null) {
|
||||
finalUrl = attachment.remote_url;
|
||||
} else {
|
||||
finalUrl = attachment.url;
|
||||
}
|
||||
layoutMediaBinding.media.setOnLongClickListener(v -> {
|
||||
if (long_press_media) {
|
||||
MediaHelper.manageMove(context, finalUrl, false);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
if (fullAttachement) {
|
||||
lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutMediaBinding.media.setScaleType(ImageView.ScaleType.FIT_CENTER);
|
||||
|
@ -1185,8 +1214,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
if (!mediaObfuscated(statusToDeal) || expand_media) {
|
||||
layoutMediaBinding.viewHide.setImageResource(R.drawable.ic_baseline_visibility_24);
|
||||
RequestBuilder<Drawable> requestBuilder = Glide.with(layoutMediaBinding.media.getContext())
|
||||
.load(attachment.preview_url)
|
||||
.apply(new RequestOptions().transform(new CenterCrop(), new RoundedCorners((int) Helper.convertDpToPixel(3, context))));
|
||||
.load(attachment.preview_url);
|
||||
if (!fullAttachement) {
|
||||
requestBuilder = requestBuilder.apply(new RequestOptions().transform(new GlideFocus(focusX, focusY)));
|
||||
}
|
||||
|
|
|
@ -69,8 +69,11 @@ public class FragmentMastodonContext extends Fragment {
|
|||
int position = getPosition(receivedStatus);
|
||||
if (position >= 0) {
|
||||
statuses.get(position).reblog = receivedStatus.reblog;
|
||||
statuses.get(position).reblogged = receivedStatus.reblogged;
|
||||
statuses.get(position).favourited = receivedStatus.favourited;
|
||||
statuses.get(position).bookmarked = receivedStatus.bookmarked;
|
||||
statuses.get(position).reblogs_count = receivedStatus.reblogs_count;
|
||||
statuses.get(position).favourites_count = receivedStatus.favourites_count;
|
||||
statusAdapter.notifyItemChanged(position);
|
||||
}
|
||||
} else if (delete_statuses_for_user != null && statusAdapter != null) {
|
||||
|
|
|
@ -76,8 +76,11 @@ public class FragmentMastodonNotification extends Fragment implements Notificati
|
|||
if (position >= 0) {
|
||||
if (notificationList.get(position).status != null) {
|
||||
notificationList.get(position).status.reblog = receivedStatus.reblog;
|
||||
notificationList.get(position).status.reblogged = receivedStatus.reblogged;
|
||||
notificationList.get(position).status.favourited = receivedStatus.favourited;
|
||||
notificationList.get(position).status.bookmarked = receivedStatus.bookmarked;
|
||||
notificationList.get(position).status.favourites_count = receivedStatus.favourites_count;
|
||||
notificationList.get(position).status.reblogs_count = receivedStatus.reblogs_count;
|
||||
notificationAdapter.notifyItemChanged(position);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,8 +92,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
int position = getPosition(receivedStatus);
|
||||
if (position >= 0) {
|
||||
statuses.get(position).reblog = receivedStatus.reblog;
|
||||
statuses.get(position).reblogged = receivedStatus.reblogged;
|
||||
statuses.get(position).favourited = receivedStatus.favourited;
|
||||
statuses.get(position).bookmarked = receivedStatus.bookmarked;
|
||||
statuses.get(position).reblogs_count = receivedStatus.reblogs_count;
|
||||
statuses.get(position).favourites_count = receivedStatus.favourites_count;
|
||||
statusAdapter.notifyItemChanged(position);
|
||||
}
|
||||
} else if (delete_statuses_for_user != null && statusAdapter != null) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
|
11
app/src/main/res/drawable/ic_baseline_notes_24.xml
Normal file
11
app/src/main/res/drawable/ic_baseline_notes_24.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M3,18h12v-2L3,16v2zM3,6v2h18L21,6L3,6zM3,13h18v-2L3,11v2z" />
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_baseline_translate_24.xml
Normal file
10
app/src/main/res/drawable/ic_baseline_translate_24.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z" />
|
||||
</vector>
|
|
@ -16,37 +16,32 @@
|
|||
-->
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="350dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/main_container"
|
||||
android:layout_height="420dp"
|
||||
android:padding="@dimen/fab_margin"
|
||||
android:paddingLeft="@dimen/drawer_padding"
|
||||
android:paddingRight="@dimen/drawer_padding">
|
||||
|
||||
<RelativeLayout
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_height="300dp"
|
||||
android:alpha="0.2">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back_ground_image"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="300dp"
|
||||
android:contentDescription="@string/logo_of_the_instance"
|
||||
android:scaleType="centerCrop" />
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/instance_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="20dp"
|
||||
android:orientation="vertical">
|
||||
<!-- Instance title -->
|
||||
<TextView
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/instance_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -55,7 +50,7 @@
|
|||
android:textSize="20sp" />
|
||||
|
||||
<!-- Instance description -->
|
||||
<TextView
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/instance_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -64,7 +59,7 @@
|
|||
android:gravity="center_horizontal"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
|
@ -72,7 +67,7 @@
|
|||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
<!-- Instance version -->
|
||||
<TextView
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/instance_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -80,7 +75,7 @@
|
|||
android:textSize="14sp"
|
||||
android:textStyle="italic" />
|
||||
<!-- Instance URI -->
|
||||
<TextView
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/instance_uri"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -88,24 +83,48 @@
|
|||
android:gravity="center_horizontal"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="italic" />
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/instance_contact"
|
||||
|
||||
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/max_char_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/instance_container"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:contentDescription="@string/contact_instance_admin"
|
||||
android:src="@drawable/ic_baseline_mail_outline_24"
|
||||
app:backgroundTint="@color/cyanea_accent_dark_reference" />
|
||||
</LinearLayout>
|
||||
android:text="@string/set_your_max_char_count"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/max_char"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:hint="500"
|
||||
android:inputType="number"
|
||||
android:textSize="18sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<!-- Main Loader -->
|
||||
<RelativeLayout
|
||||
android:id="@+id/loader"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="420dp"
|
||||
android:gravity="center"
|
||||
tools:visibility="visible"
|
||||
android:visibility="gone">
|
||||
|
||||
<ProgressBar
|
||||
|
@ -114,7 +133,23 @@
|
|||
android:indeterminate="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/instance_contact"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:contentDescription="@string/contact_instance_admin"
|
||||
android:src="@drawable/ic_baseline_mail_outline_24"
|
||||
app:backgroundTint="@color/cyanea_accent_dark_reference"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/max_char_container"
|
||||
android:id="@+id/close"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -122,10 +157,10 @@
|
|||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="@string/close"
|
||||
android:textAllCaps="false"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="16sp" />
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
86
app/src/main/res/layout/drawer_release_note.xml
Normal file
86
app/src/main/res/layout/drawer_release_note.xml
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/version"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:padding="2dp"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/note"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/translate"
|
||||
style="@style/Widget.App.Button.IconOnly.Outline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:contentDescription="@string/translate"
|
||||
app:icon="@drawable/ic_baseline_translate_24"
|
||||
app:iconPadding="0dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/container_trans"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<View
|
||||
android:id="@+id/translation_border_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:background="@drawable/translation_border"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/translation_border_top" />
|
||||
|
||||
<androidx.constraintlayout.widget.Placeholder
|
||||
android:id="@+id/translation_border_top"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="1dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/translation_label"
|
||||
app:layout_constraintEnd_toEndOf="@id/translation_label"
|
||||
app:layout_constraintTop_toTopOf="@id/translation_label" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/translation_label"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:background="?backgroundColorLight"
|
||||
android:paddingStart="2dp"
|
||||
android:paddingEnd="2dp"
|
||||
android:text="@string/translation"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/note_translated"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/translation_label"
|
||||
app:layout_goneMarginBottom="8dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -147,6 +147,19 @@
|
|||
app:layout_constraintStart_toEndOf="@id/button_visibility"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_area_divider" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/button_emoji_one"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:contentDescription="@string/emoji_picker"
|
||||
android:src="@drawable/ic_baseline_insert_emoticon_24"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toEndOf="@id/button_emoji"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_area_divider"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/character_count"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -155,7 +168,7 @@
|
|||
android:text="0"
|
||||
app:layout_constraintBottom_toTopOf="@id/character_progress"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_post"
|
||||
app:layout_constraintStart_toEndOf="@id/button_emoji"
|
||||
app:layout_constraintStart_toEndOf="@id/button_emoji_one"
|
||||
app:layout_constraintTop_toBottomOf="@id/text_area_divider"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
@ -167,7 +180,7 @@
|
|||
android:layout_height="12dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/button_post"
|
||||
app:layout_constraintStart_toEndOf="@id/button_emoji"
|
||||
app:layout_constraintStart_toEndOf="@id/button_emoji_one"
|
||||
app:layout_constraintTop_toBottomOf="@id/character_count" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
|
|
111
app/src/main/res/layout/popup_release_notes.xml
Normal file
111
app/src/main/res/layout/popup_release_notes.xml
Normal file
|
@ -0,0 +1,111 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Copyright 2022 Thomas Schneider
|
||||
|
||||
This file is a part of Fedilab
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
see <http://www.gnu.org/licenses>.
|
||||
-->
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/releasenotes"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_margin="5dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/acccount_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="@+id/about_support"
|
||||
tools:visibility="visible">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/account_pp"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_margin="10dp"
|
||||
android:contentDescription="@string/profile_picture" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/account_dn"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/account_un"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textSize="14sp" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageButton
|
||||
android:id="@+id/account_follow"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_margin="10dp"
|
||||
android:contentDescription="@string/make_an_action"
|
||||
android:scaleType="fitCenter"
|
||||
android:tint="@color/white"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintStart_toEndOf="@id/avatar_container"
|
||||
app:layout_constraintTop_toBottomOf="@id/banner_container"
|
||||
tools:src="@drawable/ic_baseline_person_add_24"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/about_support"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:text="@string/support_the_app_on_liberapay"
|
||||
android:textColor="@color/cyanea_accent_dark_reference"
|
||||
app:strokeColor="@color/cyanea_accent_dark_reference" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/about_support_paypal"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="PayPal"
|
||||
android:textColor="@color/cyanea_accent_dark_reference"
|
||||
app:strokeColor="@color/cyanea_accent_dark_reference"
|
||||
tools:ignore="HardcodedText" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
|
@ -3,74 +3,103 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:showIn="navigation_view">
|
||||
|
||||
<group android:checkableBehavior="single">
|
||||
<group>
|
||||
<item
|
||||
android:id="@+id/nav_main_com"
|
||||
android:title="@string/my_account">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/nav_drafts"
|
||||
android:icon="@drawable/ic_baseline_drafts_24"
|
||||
android:title="@string/drafts" />
|
||||
<item
|
||||
android:id="@+id/nav_interactions"
|
||||
android:icon="@drawable/ic_baseline_supervised_user_circle_24"
|
||||
android:title="@string/interactions" />
|
||||
<item
|
||||
android:id="@+id/nav_filter"
|
||||
android:icon="@drawable/ic_baseline_filter_list_24"
|
||||
android:title="@string/filters" />
|
||||
<item
|
||||
android:id="@+id/nav_list"
|
||||
android:icon="@drawable/ic_baseline_view_list_24"
|
||||
android:title="@string/action_lists" />
|
||||
<item
|
||||
android:id="@+id/nav_follow_requests"
|
||||
android:icon="@drawable/ic_baseline_group_add_24"
|
||||
android:title="@string/follow_request"
|
||||
android:visible="false" />
|
||||
<item
|
||||
android:id="@+id/nav_administration"
|
||||
android:icon="@drawable/ic_baseline_admin_panel_settings_24"
|
||||
android:title="@string/administration"
|
||||
android:visible="false" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/nav_instance"
|
||||
android:title="@string/my_instance">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/nav_announcements"
|
||||
android:icon="@drawable/ic_baseline_message_24"
|
||||
android:title="@string/action_announcements"
|
||||
android:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_drafts"
|
||||
android:icon="@drawable/ic_baseline_drafts_24"
|
||||
android:title="@string/drafts" />
|
||||
<item
|
||||
android:id="@+id/nav_reorder"
|
||||
android:icon="@drawable/ic_baseline_reorder_24"
|
||||
android:title="@string/reorder_timelines" />
|
||||
<item
|
||||
android:id="@+id/nav_trends"
|
||||
android:icon="@drawable/ic_baseline_trending_up_24"
|
||||
android:title="@string/trending"
|
||||
android:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_interactions"
|
||||
android:icon="@drawable/ic_baseline_supervised_user_circle_24"
|
||||
android:title="@string/interactions" />
|
||||
<item
|
||||
android:id="@+id/nav_about_instance"
|
||||
android:icon="@drawable/ic_info_outline_white_24dp"
|
||||
android:title="@string/action_about_instance"
|
||||
android:visible="true" />
|
||||
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
<item
|
||||
android:id="@+id/nav_filter"
|
||||
android:icon="@drawable/ic_baseline_filter_list_24"
|
||||
android:title="@string/filters" />
|
||||
android:id="@+id/nav_app"
|
||||
android:title="@string/my_app">
|
||||
<menu>
|
||||
<group android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/nav_reorder"
|
||||
android:icon="@drawable/ic_baseline_reorder_24"
|
||||
android:title="@string/reorder_timelines" />
|
||||
<item
|
||||
android:id="@+id/nav_scheduled"
|
||||
android:icon="@drawable/ic_baseline_schedule_24"
|
||||
android:title="@string/scheduled" />
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_baseline_settings_24"
|
||||
android:title="@string/settings" />
|
||||
<item
|
||||
android:id="@+id/nav_cache"
|
||||
android:icon="@drawable/ic_baseline_cached_24"
|
||||
android:title="@string/action_cache" />
|
||||
<item
|
||||
android:id="@+id/nav_about"
|
||||
android:icon="@drawable/ic_baseline_info_24"
|
||||
android:title="@string/action_about" />
|
||||
<item
|
||||
android:id="@+id/nav_release_notes"
|
||||
android:icon="@drawable/ic_baseline_notes_24"
|
||||
android:title="@string/release_notes" />
|
||||
<item
|
||||
android:id="@+id/nav_partnership"
|
||||
android:icon="@drawable/ic_baseline_account_circle_24"
|
||||
android:title="@string/action_partnership" />
|
||||
</group>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_list"
|
||||
android:icon="@drawable/ic_baseline_view_list_24"
|
||||
android:title="@string/action_lists" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_announcements"
|
||||
android:icon="@drawable/ic_baseline_message_24"
|
||||
android:title="@string/action_announcements"
|
||||
android:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_trends"
|
||||
android:icon="@drawable/ic_baseline_trending_up_24"
|
||||
android:title="@string/trending"
|
||||
android:visible="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_scheduled"
|
||||
android:icon="@drawable/ic_baseline_schedule_24"
|
||||
android:title="@string/scheduled" />
|
||||
<item
|
||||
android:id="@+id/nav_follow_requests"
|
||||
android:icon="@drawable/ic_baseline_group_add_24"
|
||||
android:title="@string/follow_request"
|
||||
android:visible="false" />
|
||||
<item
|
||||
android:id="@+id/nav_administration"
|
||||
android:icon="@drawable/ic_baseline_admin_panel_settings_24"
|
||||
android:title="@string/administration"
|
||||
android:visible="false" />
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_baseline_settings_24"
|
||||
android:title="@string/settings" />
|
||||
<item
|
||||
android:id="@+id/nav_cache"
|
||||
android:icon="@drawable/ic_baseline_cached_24"
|
||||
android:title="@string/action_cache" />
|
||||
<item
|
||||
android:id="@+id/nav_about"
|
||||
android:icon="@drawable/ic_baseline_info_24"
|
||||
android:title="@string/action_about" />
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_partnership"
|
||||
android:icon="@drawable/ic_baseline_account_circle_24"
|
||||
android:title="@string/action_partnership" />
|
||||
</group>
|
||||
</menu>
|
|
@ -1,11 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_about_instance"
|
||||
android:title="@string/action_about_instance"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
|
||||
<item
|
||||
android:id="@+id/action_proxy"
|
||||
android:title="@string/proxy_set"
|
||||
app:showAsAction="never" />
|
||||
|
|
|
@ -721,4 +721,9 @@
|
|||
<string name="delete_cache_message">Ses seguru de bòlere isboidare sa memòria temporànea\? Si tenes abbotzos cun cuntenutos multimediales as a pèrdere sos cuntenutos alligados.</string>
|
||||
<string name="clear_cache">Isbòida sa memòria temporànea</string>
|
||||
<string name="default_system_language">Imprea sa limba predefinida de sistema</string>
|
||||
<string name="message_language">Limba pro sos messàgios</string>
|
||||
<string name="my_instance">S\'istàntzia mea</string>
|
||||
<string name="my_app">S\'aplicatzione mea</string>
|
||||
<string name="set_your_max_char_count">Imposta su nùmeru màssimu de caràteres tuo</string>
|
||||
<string name="my_account">Su contu meu</string>
|
||||
</resources>
|
|
@ -727,4 +727,9 @@
|
|||
<string name="messages_in_cache_for_other_timelines">Diğer zaman çizelgeleri için önbellekteki mesajlar</string>
|
||||
<string name="messages_stored_in_drafts">Taslaklarda saklanan mesajlar</string>
|
||||
<string name="default_system_language">Öntanımlı sistem dilini kullan</string>
|
||||
<string name="message_language">Mesajlar için dil</string>
|
||||
<string name="my_instance">Sunucum</string>
|
||||
<string name="my_app">Uygulamam</string>
|
||||
<string name="my_account">Hesabım</string>
|
||||
<string name="set_your_max_char_count">Azami karakter sayınızı ayarlayın</string>
|
||||
</resources>
|
|
@ -848,7 +848,7 @@
|
|||
</string-array>
|
||||
|
||||
|
||||
<string name="SET_LONG_PRESS_MEDIA" translatable="false">SET_LONG_PRESS_MEDIA</string>
|
||||
<string name="SET_LONG_PRESS_STORE_MEDIA" translatable="false">SET_LONG_PRESS_STORE_MEDIA</string>
|
||||
<string name="SET_UNFOLLOW_VALIDATION" translatable="false">SET_UNFOLLOW_VALIDATION</string>
|
||||
<string name="SET_DISPLAY_ADMIN_STATUSES" translatable="false">SET_DISPLAY_ADMIN_STATUSES</string>
|
||||
<string name="SET_LED_COLOUR_VAL" translatable="false">SET_LED_COLOUR_VAL</string>
|
||||
|
@ -922,6 +922,10 @@
|
|||
<string name="REPLACE_WIKIPEDIA_HOST" translatable="false">REPLACE_WIKIPEDIA_HOST</string>
|
||||
<string name="DEFAULT_REPLACE_WIKIPEDIA_HOST" translatable="false">wikiless.org</string>
|
||||
<string name="LAST_NOTIFICATION_ID" translatable="false">LAST_NOTIFICATION_ID</string>
|
||||
<string name="SET_MAX_INSTANCE_CHAR" translatable="false">SET_MAX_INSTANCE_CHAR</string>
|
||||
<string name="SET_POPUP_RELEASE_NOTES" translatable="false">SET_POPUP_RELEASE_NOTES</string>
|
||||
|
||||
|
||||
<string name="type_of_notifications">Type of notifications</string>
|
||||
<string name="type_of_notifications_title">Chose the type of notifications</string>
|
||||
<string name="notification_sounds">Notification sounds</string>
|
||||
|
@ -982,6 +986,11 @@
|
|||
<string name="delete_cache_message">Are you sure you want to delete cache? If you have drafts with media, the attached media will be lost.</string>
|
||||
<string name="default_system_language">Use the default system language</string>
|
||||
<string name="message_language">Language for messages</string>
|
||||
<string name="my_instance">My instance</string>
|
||||
<string name="my_app">My app</string>
|
||||
<string name="my_account">My account</string>
|
||||
<string name="set_your_max_char_count">Set your max char count</string>
|
||||
<string name="release_notes">Release notes</string>
|
||||
|
||||
<string-array name="photo_editor_emoji" translatable="false">
|
||||
<!-- Smiles -->
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
app:iconSpaceReserved="false"
|
||||
android:defaultValue="false"
|
||||
app:singleLineTitle="false"
|
||||
app:key="@string/SET_LONG_PRESS_MEDIA"
|
||||
app:key="@string/SET_LONG_PRESS_STORE_MEDIA"
|
||||
app:title="@string/set_long_press_media" />
|
||||
<SwitchPreferenceCompat
|
||||
app:iconSpaceReserved="false"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Added:
|
||||
- Allow to define the max chars count when not detected (In about the instance)
|
||||
- Add emoji one picker when composing (must be enabled in settings)
|
||||
- Add release notes with the ability to translate them
|
||||
|
||||
Fixed:
|
||||
- Friendica custom emojis not displayed
|
||||
- Long press to store media
|
||||
- Some bug fixes
|
Loading…
Reference in a new issue