Merge branch 'develop'

This commit is contained in:
Konrad Pozniak 2020-12-20 19:01:02 +01:00
commit af18d30c05
48 changed files with 369 additions and 285 deletions

View file

@ -20,8 +20,8 @@ android {
applicationId APP_ID
minSdkVersion 21
targetSdkVersion 29
versionCode 77
versionName "13.0"
versionCode 78
versionName "13.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -101,8 +101,8 @@ ext.roomVersion = '2.2.5'
ext.retrofitVersion = '2.9.0'
ext.okhttpVersion = '4.9.0'
ext.glideVersion = '4.11.0'
ext.daggerVersion = '2.29.1'
ext.materialdrawerVersion = '8.1.8'
ext.daggerVersion = '2.30.1'
ext.materialdrawerVersion = '8.2.0'
// if libraries are changed here, they should also be changed in LicenseActivity
dependencies {
@ -111,10 +111,10 @@ dependencies {
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation "androidx.browser:browser:1.2.0"
implementation "androidx.browser:browser:1.3.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.exifinterface:exifinterface:1.3.1"
implementation "androidx.exifinterface:exifinterface:1.3.2"
implementation "androidx.cardview:cardview:1.0.0"
implementation "androidx.preference:preference-ktx:1.1.1"
implementation "androidx.sharetarget:sharetarget:1.0.0"
@ -139,8 +139,9 @@ dependencies {
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttpVersion"
implementation "com.squareup.okhttp3:okhttp-tls:$okhttpVersion"
implementation "org.conscrypt:conscrypt-android:2.4.0"
implementation "org.conscrypt:conscrypt-android:2.5.1"
implementation "com.github.bumptech.glide:glide:$glideVersion"
implementation "com.github.bumptech.glide:okhttp3-integration:$glideVersion"
@ -158,7 +159,7 @@ dependencies {
implementation "com.google.dagger:dagger-android-support:$daggerVersion"
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
implementation "com.github.connyduck:sparkbutton:4.0.0"
implementation "com.github.connyduck:sparkbutton:4.1.0"
implementation "com.github.chrisbanes:PhotoView:2.3.0"
@ -172,7 +173,7 @@ dependencies {
testImplementation "androidx.test.ext:junit:1.1.2"
testImplementation "org.robolectric:robolectric:4.4"
testImplementation "org.mockito:mockito-inline:3.6.0"
testImplementation "org.mockito:mockito-inline:3.6.28"
testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0"

View file

@ -139,12 +139,9 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
}
}
val accountRequested = accountId != -1L
if (accountRequested) {
val account = accountManager.activeAccount
if (account == null || accountId != account.id) {
if (accountRequested && accountId != activeAccount.id) {
accountManager.setActiveAccount(accountId)
}
}
if (canHandleMimeType(intent.type)) {
// Sharing to Tusky from an external app
if (accountRequested) {
@ -155,8 +152,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
showAccountChooserDialog(getString(R.string.action_share_as), true, object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
val requestedId = account.id
val activeAccount = accountManager.activeAccount
if (activeAccount != null && requestedId == activeAccount.id) {
if (requestedId == activeAccount.id) {
// The correct account is already active
forwardShare(intent)
} else {

View file

@ -22,7 +22,6 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.entity.MastoList
import com.keylesspalace.tusky.util.ThemeUtils
import kotlinx.android.synthetic.main.item_picker_list.view.*
class ListSelectionAdapter(context: Context) : ArrayAdapter<MastoList>(context, R.layout.item_autocomplete_hashtag) {
@ -34,10 +33,7 @@ class ListSelectionAdapter(context: Context) : ArrayAdapter<MastoList>(context,
?: layoutInflater.inflate(R.layout.item_picker_list, parent, false)
getItem(position)?.let { list ->
val title = view.title
title.text = list.title
val icon = ThemeUtils.getTintedDrawable(context, R.drawable.ic_list, R.attr.iconColor)
title.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)
view.title.text = list.title
}
return view

View file

@ -22,7 +22,6 @@ import android.widget.TextView
import androidx.core.widget.TextViewCompat
import androidx.recyclerview.widget.RecyclerView
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.util.ThemeUtils
class PreviewPollOptionsAdapter: RecyclerView.Adapter<PreviewViewHolder>() {
@ -55,9 +54,7 @@ class PreviewPollOptionsAdapter: RecyclerView.Adapter<PreviewViewHolder>() {
R.drawable.ic_radio_button_unchecked_18dp
}
val iconDrawable = ThemeUtils.getTintedDrawable(textView.context, iconId, android.R.attr.textColorTertiary)
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, iconDrawable, null, null, null)
TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, iconId, 0, 0, 0)
textView.text = options[position]

View file

@ -57,7 +57,6 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import at.connyduck.sparkbutton.SparkButton;
import at.connyduck.sparkbutton.helpers.Utils;
@ -566,9 +565,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
// Set the icon next to the label.
int drawableId = getLabelIcon(attachments.get(0).getType());
Drawable drawable = Objects.requireNonNull(context.getDrawable(drawableId));
ThemeUtils.setDrawableTint(context, drawable, android.R.attr.textColorTertiary);
mediaLabel.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
mediaLabel.setCompoundDrawablesWithIntrinsicBounds(drawableId, 0, 0, 0);
setAttachmentClickListener(mediaLabel, listener, i, attachment, false);
} else {

View file

@ -15,6 +15,7 @@
package com.keylesspalace.tusky.adapter
import android.content.res.ColorStateList
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
@ -68,8 +69,7 @@ class TabAdapter(private var data: List<TabData>,
} else {
holder.itemView.textView.setText(tab.text)
}
val iconDrawable = ThemeUtils.getTintedDrawable(context, tab.icon, android.R.attr.textColorSecondary)
holder.itemView.textView.setCompoundDrawablesRelativeWithIntrinsicBounds(iconDrawable, null, null, null)
holder.itemView.textView.setCompoundDrawablesRelativeWithIntrinsicBounds(tab.icon, 0, 0, 0)
if (small) {
holder.itemView.textView.setOnClickListener {
listener.onTabAdded(tab)
@ -110,6 +110,7 @@ class TabAdapter(private var data: List<TabData>,
val chip = holder.itemView.chipGroup.getChildAt(i).takeUnless { it.id == R.id.actionChip } as Chip?
?: Chip(context).apply {
holder.itemView.chipGroup.addView(this, holder.itemView.chipGroup.size - 1)
chipIconTint = ColorStateList.valueOf(ThemeUtils.getColor(context, android.R.attr.textColorPrimary))
}
chip.text = arg
@ -118,8 +119,7 @@ class TabAdapter(private var data: List<TabData>,
chip.chipIcon = null
chip.setOnClickListener(null)
} else {
val cancelIcon = ThemeUtils.getTintedDrawable(context, R.drawable.ic_cancel_24dp, android.R.attr.textColorPrimary)
chip.chipIcon = cancelIcon
chip.setChipIconResource(R.drawable.ic_cancel_24dp)
chip.setOnClickListener {
listener.onChipClicked(tab, holder.adapterPosition, i)
}

View file

@ -534,8 +534,7 @@ class ComposeActivity : BaseActivity(),
Status.Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp
else -> R.drawable.ic_lock_open_24dp
}
val drawable = ThemeUtils.getTintedDrawable(this, iconRes, android.R.attr.textColorTertiary)
composeToggleVisibilityButton.setImageDrawable(drawable)
composeToggleVisibilityButton.setImageResource(iconRes)
}
private fun showComposeOptions() {

View file

@ -26,13 +26,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import com.google.android.material.datepicker.CalendarConstraints;
import com.google.android.material.datepicker.DateValidatorPointForward;
import com.google.android.material.datepicker.MaterialDatePicker;
import com.keylesspalace.tusky.R;
import com.keylesspalace.tusky.fragment.TimePickerFragment;
import com.keylesspalace.tusky.util.ThemeUtils;
import java.text.DateFormat;
import java.text.ParseException;
@ -106,7 +106,7 @@ public class ComposeScheduleView extends ConstraintLayout {
}
private void setEditIcons() {
Drawable icon = ThemeUtils.getTintedDrawable(getContext(), R.drawable.ic_create_24dp, android.R.attr.textColorTertiary);
Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_create_24dp);
if (icon == null) {
return;
}

View file

@ -16,10 +16,10 @@
package com.keylesspalace.tusky.components.preference
import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.annotation.DrawableRes
import androidx.preference.PreferenceFragmentCompat
import com.google.android.material.snackbar.Snackbar
import com.keylesspalace.tusky.*
@ -71,7 +71,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
preference {
setTitle(R.string.title_tab_preferences)
icon = getTintedIcon(R.drawable.ic_tabs)
setIcon(R.drawable.ic_tabs)
setOnPreferenceClickListener {
val intent = Intent(context, TabPreferenceActivity::class.java)
activity?.startActivity(intent)
@ -83,7 +83,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
preference {
setTitle(R.string.action_view_mutes)
icon = getTintedIcon(R.drawable.ic_mute_24dp)
setIcon(R.drawable.ic_mute_24dp)
setOnPreferenceClickListener {
val intent = Intent(context, AccountListActivity::class.java)
intent.putExtra("type", AccountListActivity.Type.MUTES)
@ -112,7 +112,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
preference {
setTitle(R.string.title_domain_mutes)
icon = getTintedIcon(R.drawable.ic_mute_24dp)
setIcon(R.drawable.ic_mute_24dp)
setOnPreferenceClickListener {
val intent = Intent(context, InstanceListActivity::class.java)
activity?.startActivity(intent)
@ -132,11 +132,9 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
val visibility = accountManager.activeAccount?.defaultPostPrivacy
?: Status.Visibility.PUBLIC
value = visibility.serverString()
icon = getIconForVisibility(visibility)
setIcon(getIconForVisibility(visibility))
setOnPreferenceChangeListener { _, newValue ->
icon = getIconForVisibility(
Status.Visibility.byString(newValue as String)
)
setIcon(getIconForVisibility(Status.Visibility.byString(newValue as String)))
syncWithServer(visibility = newValue)
eventHub.dispatch(PreferenceChangedEvent(key))
true
@ -151,9 +149,9 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
val sensitivity = accountManager.activeAccount?.defaultMediaSensitivity
?: false
setDefaultValue(sensitivity)
icon = getIconForSensitivity(sensitivity)
setIcon(getIconForSensitivity(sensitivity))
setOnPreferenceChangeListener { _, newValue ->
icon = getIconForSensitivity(newValue as Boolean)
setIcon(getIconForSensitivity(newValue as Boolean))
syncWithServer(sensitive = newValue)
eventHub.dispatch(PreferenceChangedEvent(key))
true
@ -303,30 +301,24 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(), Injectable {
}
}
private fun getIconForVisibility(visibility: Status.Visibility): Drawable? {
val drawableId = when (visibility) {
@DrawableRes
private fun getIconForVisibility(visibility: Status.Visibility): Int {
return when (visibility) {
Status.Visibility.PRIVATE -> R.drawable.ic_lock_outline_24dp
Status.Visibility.UNLISTED -> R.drawable.ic_lock_open_24dp
else -> R.drawable.ic_public_24dp
}
return getTintedIcon(drawableId)
}
private fun getIconForSensitivity(sensitive: Boolean): Drawable? {
val drawableId = if (sensitive) {
@DrawableRes
private fun getIconForSensitivity(sensitive: Boolean): Int {
return if (sensitive) {
R.drawable.ic_hide_media_24dp
} else {
R.drawable.ic_eye_24dp
}
return getTintedIcon(drawableId)
}
private fun getTintedIcon(iconId: Int): Drawable? {
return ThemeUtils.getTintedDrawable(requireContext(), iconId, R.attr.iconColor)
}
private fun launchFilterActivity(filterContext: String, titleResource: Int) {

View file

@ -39,7 +39,6 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
private var httpProxyPref: Preference? = null
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
val context = requireContext()
makePreferenceScreen {
preferenceCategory(R.string.pref_title_appearance_settings) {
listPreference {
@ -115,11 +114,8 @@ class PreferencesFragment : PreferenceFragmentCompat(), Injectable {
key = PrefKeys.SHOW_BOT_OVERLAY
setTitle(R.string.pref_title_bot_overlay)
isSingleLineTitle = false
icon = ThemeUtils.getTintedDrawable(
context,
R.drawable.ic_bot_24dp,
R.attr.iconColor
)
setIcon(R.drawable.ic_bot_24dp)
}
switchPreference {

View file

@ -24,7 +24,7 @@ import com.keylesspalace.tusky.db.AccountManager
import com.keylesspalace.tusky.json.SpannedTypeAdapter
import com.keylesspalace.tusky.network.InstanceSwitchAuthInterceptor
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.OkHttpUtils
import com.keylesspalace.tusky.util.okhttpClient
import dagger.Module
import dagger.Provides
import okhttp3.OkHttpClient
@ -32,6 +32,7 @@ import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create
import javax.inject.Singleton
/**
@ -55,7 +56,7 @@ class NetworkModule {
accountManager: AccountManager,
context: Context
): OkHttpClient {
return OkHttpUtils.getCompatibleClientBuilder(context)
return okhttpClient(context)
.apply {
addInterceptor(InstanceSwitchAuthInterceptor(accountManager))
if (BuildConfig.DEBUG) {
@ -81,5 +82,5 @@ class NetworkModule {
@Provides
@Singleton
fun providesApi(retrofit: Retrofit): MastodonApi = retrofit.create(MastodonApi::class.java)
fun providesApi(retrofit: Retrofit): MastodonApi = retrofit.create()
}

View file

@ -1,87 +0,0 @@
/* Copyright 2017 Andrew Dawson
*
* This file is part of Tusky.
*
* Tusky is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Tusky 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with Tusky. If
* not, see <http://www.gnu.org/licenses/>. */
package com.keylesspalace.tusky.util;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.preference.PreferenceManager;
import com.keylesspalace.tusky.BuildConfig;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class OkHttpUtils {
@NonNull
public static OkHttpClient.Builder getCompatibleClientBuilder(@NonNull Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
boolean httpProxyEnabled = preferences.getBoolean("httpProxyEnabled", false);
String httpServer = preferences.getString("httpProxyServer", "");
int httpPort;
try {
httpPort = Integer.parseInt(preferences.getString("httpProxyPort", "-1"));
} catch (NumberFormatException e) {
// user has entered wrong port, fall back to no proxy
httpPort = -1;
}
int cacheSize = 25*1024*1024; // 25 MiB
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(getUserAgentInterceptor())
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.cache(new Cache(context.getCacheDir(), cacheSize));
if (httpProxyEnabled && !httpServer.isEmpty() && (httpPort > 0) && (httpPort < 65535)) {
InetSocketAddress address = InetSocketAddress.createUnresolved(httpServer, httpPort);
builder.proxy(new Proxy(Proxy.Type.HTTP, address));
}
return builder;
}
/**
* Add a custom User-Agent that contains Tusky & Android Version to all requests
* Example:
* User-Agent: Tusky/1.1.2 Android/5.0.2
*/
@NonNull
private static Interceptor getUserAgentInterceptor() {
return chain -> {
Request originalRequest = chain.request();
Request requestWithUserAgent = originalRequest.newBuilder()
.header("User-Agent", "Tusky/"+ BuildConfig.VERSION_NAME+" Android/"+Build.VERSION.RELEASE)
.build();
return chain.proceed(requestWithUserAgent);
};
}
}

View file

@ -0,0 +1,115 @@
/* Copyright 2020 Tusky Contributors
*
* This file is part of Tusky.
*
* Tusky is free software: you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* Tusky 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 Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with Tusky. If
* not, see <http://www.gnu.org/licenses/>. */
package com.keylesspalace.tusky.util
import android.content.Context
import android.os.Build
import androidx.preference.PreferenceManager
import com.keylesspalace.tusky.BuildConfig
import okhttp3.Cache
import okhttp3.OkHttp
import okhttp3.OkHttpClient
import okhttp3.tls.HandshakeCertificates
import java.io.ByteArrayInputStream
import java.net.InetSocketAddress
import java.net.Proxy
import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
fun okhttpClient(context: Context): OkHttpClient.Builder {
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
val httpProxyEnabled = preferences.getBoolean("httpProxyEnabled", false)
val httpServer = preferences.getNonNullString("httpProxyServer", "")
val httpPort = preferences.getNonNullString("httpProxyPort", "-1").toIntOrNull() ?: -1
val cacheSize = 25 * 1024 * 1024 // 25 MiB
val builder = OkHttpClient.Builder()
.addInterceptor { chain ->
/**
* Add a custom User-Agent that contains Tusky, Android and Okhttp Version to all requests
* Example:
* User-Agent: Tusky/1.1.2 Android/5.0.2
* */
val requestWithUserAgent = chain.request().newBuilder()
.header(
"User-Agent",
"Tusky/${BuildConfig.VERSION_NAME} Android/${Build.VERSION.RELEASE} OkHttp/${OkHttp.VERSION}"
)
.build()
chain.proceed(requestWithUserAgent)
}
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.cache(Cache(context.cacheDir, cacheSize.toLong()))
if (httpProxyEnabled && httpServer.isNotEmpty() && httpPort > 0 && httpPort < 65535) {
val address = InetSocketAddress.createUnresolved(httpServer, httpPort)
builder.proxy(Proxy(Proxy.Type.HTTP, address))
}
// trust the new Let's Encrypt root certificate that is not available on Android < 7.1.1
// new cert https://letsencrypt.org/certs/isrgrootx1.pem
// see https://letsencrypt.org/2020/11/06/own-two-feet.html
// see https://stackoverflow.com/questions/64844311/certpathvalidatorexception-connecting-to-a-lets-encrypt-host-on-android-m-or-ea
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
val isgCert = """
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
""".trimIndent()
val cf = CertificateFactory.getInstance("X.509")
val isgCertificate = cf.generateCertificate(ByteArrayInputStream(isgCert.toByteArray(charset("UTF-8"))))
val certificates = HandshakeCertificates.Builder()
.addTrustedCertificate(isgCertificate as X509Certificate)
.addPlatformTrustedCertificates()
.build()
builder.sslSocketFactory(
certificates.sslSocketFactory(),
certificates.trustManager
)
}
return builder
}

View file

@ -23,7 +23,6 @@ import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.appcompat.content.res.AppCompatResources
import com.bumptech.glide.Glide
import com.keylesspalace.tusky.R
import com.keylesspalace.tusky.entity.Attachment
@ -220,9 +219,7 @@ class StatusViewHelper(private val itemView: View) {
// Set the icon next to the label.
val drawableId = getLabelIcon(attachments[0].type)
val drawable = AppCompatResources.getDrawable(context, drawableId)
ThemeUtils.setDrawableTint(context, drawable!!, android.R.attr.textColorTertiary)
mediaLabel.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null)
mediaLabel.setCompoundDrawablesWithIntrinsicBounds(drawableId, 0, 0, 0)
mediaLabel.setOnClickListener { listener.onViewMedia(null, 0) }
}

View file

@ -22,9 +22,7 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDelegate;
import android.util.TypedValue;
@ -59,17 +57,6 @@ public class ThemeUtils {
return dimen;
}
/** this can be replaced with drawableTint in xml once minSdkVersion >= 23 */
@Nullable
public static Drawable getTintedDrawable(@NonNull Context context, @DrawableRes int drawableId, @AttrRes int colorAttr) {
Drawable drawable = context.getDrawable(drawableId);
if(drawable == null) {
return null;
}
setDrawableTint(context, drawable, colorAttr);
return drawable;
}
public static void setDrawableTint(Context context, Drawable drawable, @AttrRes int attribute) {
drawable.setColorFilter(getColor(context, attribute), PorterDuff.Mode.SRC_IN);
}

View file

@ -136,10 +136,10 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/composeMediaPreviewBar"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="none" />
android:scrollbars="none"
android:visibility="gone" />
<com.keylesspalace.tusky.components.compose.view.PollPreviewView
android:id="@+id/pollPreview"
@ -239,9 +239,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:animateLayoutChanges="true"
android:background="?attr/colorSurface"
android:elevation="12dp"
android:animateLayoutChanges="true"
android:gravity="center_vertical"
android:paddingStart="8dp"
android:paddingTop="4dp"
@ -256,8 +256,8 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/action_add_media"
android:padding="4dp"
android:tooltipText="@string/action_add_media"
app:srcCompat="@drawable/ic_attach_file_24dp" />
app:srcCompat="@drawable/ic_attach_file_24dp"
app:tooltipText="@string/action_add_media" />
<ImageButton
android:id="@+id/composeToggleVisibilityButton"
@ -267,7 +267,8 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/action_toggle_visibility"
android:padding="4dp"
android:tooltipText="@string/action_toggle_visibility"
android:tint="?android:attr/textColorTertiary"
app:tooltipText="@string/action_toggle_visibility"
tools:src="@drawable/ic_public_24dp" />
<ImageButton
@ -278,7 +279,7 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/action_hide_media"
android:padding="4dp"
android:tooltipText="@string/action_hide_media"
app:tooltipText="@string/action_hide_media"
tools:src="@drawable/ic_eye_24dp" />
<ImageButton
@ -289,8 +290,8 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/action_content_warning"
android:padding="4dp"
android:tooltipText="@string/action_content_warning"
app:srcCompat="@drawable/ic_cw_24dp" />
app:srcCompat="@drawable/ic_cw_24dp"
app:tooltipText="@string/action_content_warning" />
<ImageButton
android:id="@+id/composeEmojiButton"
@ -300,8 +301,8 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/action_emoji_keyboard"
android:padding="4dp"
android:tooltipText="@string/action_emoji_keyboard"
app:srcCompat="@drawable/ic_emoji_24dp" />
app:srcCompat="@drawable/ic_emoji_24dp"
app:tooltipText="@string/action_emoji_keyboard" />
<ImageButton
android:id="@+id/composeScheduleButton"
@ -311,8 +312,8 @@
android:layout_marginEnd="4dp"
android:contentDescription="@string/action_schedule_toot"
android:padding="4dp"
android:tooltipText="@string/action_schedule_toot"
app:srcCompat="@drawable/ic_access_time" />
app:srcCompat="@drawable/ic_access_time"
app:tooltipText="@string/action_schedule_toot" />
<Space
android:layout_width="0dp"

View file

@ -23,7 +23,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentInsetStartWithNavigation="0dp"
app:layout_scrollFlags="scroll|enterAlways" />
app:layout_scrollFlags="scroll|enterAlways"
app:navigationContentDescription="@string/action_open_drawer" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"

View file

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/hashtag"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:textSize="?attr/status_text_medium"
android:textStyle="normal|bold" />
android:textStyle="normal|bold"
app:drawableStartCompat="@drawable/ic_list"
app:drawableTint="?attr/iconColor" />

View file

@ -340,6 +340,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -353,6 +354,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_0" />
@ -366,6 +368,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_1" />
@ -379,6 +382,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />

View file

@ -6,8 +6,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="8dp"
android:paddingTop="8dp">
android:paddingTop="8dp"
android:paddingBottom="8dp">
<!--This is a thumbnail picture-->
<ImageView
@ -15,23 +15,25 @@
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginStart="16dp"
android:importantForAccessibility="no"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_emoji_24dp" />
app:srcCompat="@drawable/ic_emoji_24dp"
app:tint="#0000" /> <!-- unset the preference theme tint -->
<!--This is the font's name-->
<TextView
android:id="@+id/emojicompat_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="72dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="72dp"
android:textColor="?android:textColorPrimary"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="?attr/status_text_medium"
app:layout_constraintBottom_toTopOf="@+id/emojicompat_caption"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/emojicompat_thumb"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/system_default" />
@ -58,8 +60,8 @@
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="72dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="72dp"
android:indeterminate="false"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"

View file

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView 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:drawablePadding="4dp"
@ -7,4 +8,5 @@
android:focusableInTouchMode="false"
android:gravity="center_vertical"
android:lines="1"
android:maxEms="20" />
android:maxEms="20"
app:drawableTint="?android:attr/textColorTertiary" />

View file

@ -198,8 +198,8 @@
app:layout_constraintLeft_toLeftOf="@+id/status_media_preview_container"
app:layout_constraintTop_toTopOf="@+id/status_media_preview_container"
app:srcCompat="@drawable/ic_eye_24dp"
tools:visibility="visible"
app:tint="@color/white" />
app:tint="@color/white"
tools:visibility="visible" />
<TextView
android:id="@+id/status_sensitive_media_warning"
@ -231,6 +231,7 @@
android:gravity="center_vertical"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

View file

@ -167,9 +167,9 @@
android:foreground="?attr/selectableItemBackground"
android:minHeight="80dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/status_display_name"
app:layout_constraintTop_toBottomOf="@+id/button_toggle_content"
app:layout_constraintEnd_toEndOf="parent"
tools:visibility="gone">
<ImageView
@ -398,6 +398,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -411,6 +412,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_0" />
@ -424,6 +426,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_1" />
@ -437,6 +440,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />

View file

@ -344,6 +344,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@ -357,6 +358,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_0" />
@ -370,6 +372,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_1" />
@ -383,6 +386,7 @@
android:importantForAccessibility="no"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_media_label_2" />

View file

@ -32,6 +32,7 @@
android:paddingBottom="8dp"
android:textColor="?android:attr/textColorSecondary"
android:textSize="?attr/status_text_large"
app:drawableTint="?android:attr/textColorSecondary"
app:layout_constraintBottom_toTopOf="@id/chipGroup"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView"

View file

@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/textView"
android:layout_width="match_parent"
android:drawableStart="@drawable/ic_home_24dp"
android:layout_height="48dp"
android:gravity="center_vertical"
android:background="?attr/selectableItemBackground"
android:drawablePadding="12dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:lines="1"
android:ellipsize="end"
android:background="?attr/selectableItemBackground"
android:textColor="?android:attr/textColorSecondary"
android:textSize="?attr/status_text_large" />
android:textSize="?attr/status_text_large"
app:drawableStartCompat="@drawable/ic_home_24dp"
app:drawableTint="?android:attr/textColorSecondary" />

View file

@ -23,6 +23,7 @@
android:paddingBottom="16dp"
android:textColor="?android:textColorTertiary"
android:textSize="?attr/status_text_medium"
app:drawableTint="?android:attr/textColorTertiary"
app:layout_constraintBottom_toTopOf="@id/invalidScheduleWarning"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
@ -39,11 +40,11 @@
android:paddingBottom="16dp"
android:textColor="?android:textColorTertiary"
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1"
app:layout_constraintStart_toStartOf="parent"
tools:text="@string/warning_scheduling_interval"
android:visibility="gone" />
tools:text="@string/warning_scheduling_interval" />
</merge>

View file

@ -381,7 +381,7 @@
<string name="poll_vote">ভোট</string>
<string name="poll_info_closed">বন্ধ</string>
<string name="poll_info_time_absolute">\'%s এ শেষ হবে\'</string>
<string name="poll_info_format">" &lt;!-- ১৫ ভোট • ১ ঘন্টা বাকি --&gt; %1$s • %2$s"<!-- 15 votes • 1 hour left -->
<string name="poll_info_format"><!-- 15 votes • 1 hour left -->
%1$s • %2$s</string>
<string name="compose_preview_image_description">ছবি %s এর জন্য ক্রিয়া</string>
<string name="notification_clear_text">আপনি কি আপনার সমস্ত বিজ্ঞপ্তি স্থায়ীভাবে মুছে ফেলতে চান\?</string>

View file

@ -475,11 +475,7 @@
<string name="action_unmute_notifications_desc">Odkrýt oznámení od %s</string>
<string name="action_unmute_desc">Odkrýt %s</string>
<string name="dialog_mute_warning">Ztišit @%s\?</string>
<plurals name="poll_info_people">
<item quantity="one"/>
<item quantity="few"/>
<item quantity="other"/>
</plurals>
<string name="notification_follow_request_format">%s požádal/a aby vás mohl/a sledovat</string>
<string name="pref_title_confirm_reblogs">Zobrazit dialogové okno s potvrzením při boostování</string>
</resources>

View file

@ -474,4 +474,12 @@
<string name="pref_title_notification_filter_follow_requests">iu petas sekvi min</string>
<string name="pref_main_nav_position_option_bottom">Malsupro</string>
<string name="pref_main_nav_position_option_top">Supro</string>
<string name="account_note_saved">Konservita!</string>
<string name="account_note_hint">Via privata noto pri ĉi tiu konto</string>
<string name="pref_title_hide_top_toolbar">Kaŝi la titolon de la supra ilobreto</string>
<string name="pref_title_show_cards_in_timelines">Montri antaŭvidojn de ligiloj en tempolinioj</string>
<string name="pref_title_confirm_reblogs">Montri konfirman fenestron antaŭ ol diskonigi</string>
<string name="no_announcements">Estas neniu anonco.</string>
<string name="pref_title_enable_swipe_for_tabs">Ebligi ŝovumadon por ŝanĝi inter la langetoj</string>
<string name="warning_scheduling_interval">Mastodon havas minimuman intervalon de planado de 5 minutoj.</string>
</resources>

View file

@ -450,10 +450,7 @@
<string name="hashtags">Traolak</string>
<string name="dialog_mute_hide_notifications">Ez erakutsi jakinarazpenak</string>
<string name="action_unmute_desc">Desmututu %s</string>
<plurals name="poll_info_people">
<item quantity="one">Pertsona %1</item>
<item quantity="other">%2 pertsona</item>
</plurals>
<string name="pref_title_hide_top_toolbar">Ezkutatu goiko tresna-barraren izenburua</string>
<string name="pref_title_confirm_reblogs">Erakutsi berrespen-abisua tuta bultzatu aurretik</string>
<string name="pref_title_show_cards_in_timelines">Erakutsi esteken aurrebista denbora-lerroetan</string>

View file

@ -150,8 +150,8 @@
<string name="pref_title_appearance_settings">ظاهر</string>
<string name="pref_title_app_theme">زمینهٔ کاره</string>
<string name="pref_title_timelines">خط‌ زمانی‌ها</string>
<string name="app_them_dark">روشن</string>
<string name="app_theme_light">سیاه</string>
<string name="app_them_dark">تاریک</string>
<string name="app_theme_light">روشن</string>
<string name="app_theme_black">سیاه</string>
<string name="app_theme_auto">خودکار در غروب</string>
<string name="pref_title_browser_settings">مرورگر</string>

View file

@ -452,18 +452,18 @@
<string name="error_audio_upload_size">Les fichiers audio doivent avoir moins de 40 Mo.</string>
<string name="no_saved_status">Vous navez aucun brouillon.</string>
<string name="no_scheduled_status">Vous navez aucun pouet planifié.</string>
<string name="warning_scheduling_interval">Lintervalle minimum de planification sur Mastodon est de5 minutes.</string>
<string name="warning_scheduling_interval">Lintervalle minimum de planification sur Mastodon est de 5 minutes.</string>
<string name="notification_follow_request_name">Demandes d\'abonnement</string>
<string name="dialog_block_warning">Bloquer @%s \?</string>
<string name="pref_title_confirm_reblogs">Afficher une fenêtre de confirmation avant de partager</string>
<string name="pref_title_show_cards_in_timelines">Afficher des aperçus des liens dans les fils</string>
<string name="pref_title_show_cards_in_timelines">Afficher les aperçus des liens dans les fils</string>
<string name="notification_follow_request_format">%s a demandé à vous suivre</string>
<string name="notification_follow_request_description">Notifications à propos des demandes dabonnement</string>
<string name="pref_title_notification_filter_follow_requests">on demande à me suivre</string>
<string name="dialog_mute_warning">Mettre en sourdine @%s \?</string>
<string name="action_unmute_conversation">Enlever la sourdine à la conversation</string>
<string name="action_mute_conversation">Masquer la conversation</string>
<string name="pref_title_enable_swipe_for_tabs">Activer les gestes de glissement pour passer dun onglet à lautre</string>
<string name="pref_title_enable_swipe_for_tabs">Activer le glissement pour changer donglet</string>
<string name="hashtags">Hashtags</string>
<string name="add_hashtag_title">Ajouter un hashtag</string>
<string name="pref_title_gradient_for_media">Afficher des dégradés en couleur pour les médias cachés</string>
@ -486,6 +486,6 @@
</plurals>
<string name="account_note_saved">Sauvegardé !</string>
<string name="account_note_hint">Votre note privée sur ce compte</string>
<string name="no_announcements">Il ny a pas dannonces.</string>
<string name="no_announcements">Il ny a pas dannonce.</string>
<string name="title_announcements">Annonces</string>
</resources>

View file

@ -3,30 +3,30 @@
<string name="error_generic">Hiba történt.</string>
<string name="error_network">Hálózati hiba történt! Kérjük, ellenőrizd a kapcsolatot, és próbálja meg újra!</string>
<string name="error_empty">Ez nem lehet üres.</string>
<string name="error_invalid_domain">Helytelen domén</string>
<string name="error_failed_app_registration">Sikertelen bejelentkezés ezen a szerveren.</string>
<string name="error_invalid_domain">Helytelen domain</string>
<string name="error_failed_app_registration">Sikertelen hitelesítés ezen a példányon.</string>
<string name="error_no_web_browser_found">Nem található használható böngésző.</string>
<string name="error_authorization_unknown">Azonosítatlan engedélyezési hiba történt.</string>
<string name="error_authorization_denied">Engedély megtagadva.</string>
<string name="error_retrieving_oauth_token">Bejelentkezési token megszerzése sikertelen.</string>
<string name="error_compose_character_limit">Túl hosszú a tülkölés!</string>
<string name="error_image_upload_size">A fájlnak kisebbnek kell lennie, mint 8MB.</string>
<string name="error_video_upload_size">A video fájlnak kisebbnek kell lennie, mint 40MB.</string>
<string name="error_image_upload_size">A fájlnak kisebbnek kell lennie, mint 8 MB.</string>
<string name="error_video_upload_size">A videofájloknak kisebbnek kell lenniük, mint 40 MB.</string>
<string name="error_media_upload_type">Ilyen típusú fájlt nem lehet feltölteni.</string>
<string name="error_media_upload_opening">Fájl megnyitása sikertelen.</string>
<string name="error_media_upload_permission">Média olvasási engedély szükséges.</string>
<string name="error_media_download_permission">Média tárolási engedély szükséges.</string>
<string name="error_media_upload_image_or_video">Képek és videók egyszerre nem csatolhatók ugyanazon tülköléshez.</string>
<string name="error_media_upload_sending">Feltöltés sikertelen.</string>
<string name="error_sender_account_gone">Nem sikerült elküldeni a tülköt..</string>
<string name="error_sender_account_gone">Nem sikerült elküldeni a tülköt.</string>
<string name="title_home">Kezdőlap</string>
<string name="title_notifications">Értesítések</string>
<string name="title_public_local">Helyi</string>
<string name="title_public_federated">Föderáció</string>
<string name="title_public_federated">Föderációs</string>
<string name="title_direct_messages">Közvetlen üzenetek</string>
<string name="title_tab_preferences">Fülek</string>
<string name="title_view_thread">Tülk</string>
<string name="title_statuses">Posztok</string>
<string name="title_statuses">Tülkök</string>
<string name="title_statuses_with_replies">Válaszokkal</string>
<string name="title_statuses_pinned">Rögzített</string>
<string name="title_follows">Követett</string>
@ -65,8 +65,8 @@
<string name="action_logout_confirm">Biztosan ki szeretnél jelentkezni a következőből: %1$s?</string>
<string name="action_follow">Követés</string>
<string name="action_unfollow">Követés vége</string>
<string name="action_block">Letiltás</string>
<string name="action_unblock">Letiltás feloldása</string>
<string name="action_block">Blokkolás</string>
<string name="action_unblock">Blokkolás feloldása</string>
<string name="action_hide_reblogs">Megtolások elrejtése</string>
<string name="action_show_reblogs">Megtolások mutatása</string>
<string name="action_report">Bejelentés</string>
@ -80,7 +80,7 @@
<string name="action_view_account_preferences">Fiókbeállítások</string>
<string name="action_view_favourites">Kedvencek</string>
<string name="action_view_mutes">Némított felhasználók</string>
<string name="action_view_blocks">Letiltott felhasználók</string>
<string name="action_view_blocks">Blokkolt felhasználók</string>
<string name="action_view_follow_requests">Követési kérelmek</string>
<string name="action_view_media">Média</string>
<string name="action_open_in_web">Megnyitás böngészőben</string>
@ -118,11 +118,11 @@
<string name="send_status_link_to">Tülk URL megosztása…</string>
<string name="send_status_content_to">Tülk megosztása…</string>
<string name="confirmation_reported">Elküldve!</string>
<string name="confirmation_unblocked">Felhasználó letiltása feloldva</string>
<string name="confirmation_unblocked">Felhasználó blokkolása feloldva</string>
<string name="confirmation_unmuted">Felhasználó némítása feloldva</string>
<string name="status_sent">Elküldve!</string>
<string name="status_sent_long">Válasz sikeresen elküldve.</string>
<string name="hint_domain">Melyik szerver\?</string>
<string name="hint_domain">Melyik példány\?</string>
<string name="hint_compose">Mi jár a fejedben\?</string>
<string name="hint_content_warning">Tartalom figyelmeztetés</string>
<string name="hint_display_name">Megjelenítési név</string>
@ -134,11 +134,11 @@
<string name="label_header">Fejléc</string>
<string name="link_whats_an_instance">Mi az a szerver\?</string>
<string name="login_connection">Csatlakozás…</string>
<string name="dialog_whats_an_instance">Bármely szerver címét beírhatod ide, mint mastodon.social, icosahedron.website, social.tchncs.de, és <a href="https://instances.social">mások!</a>
<string name="dialog_whats_an_instance">Bármely példány címét vagy domain nevét beírhatod ide, mint a mastodon.social, az icosahedron.website, a social.tchncs.de és <a href="https://instances.social">mások!</a>
\n
\nHa még nincs fiókod, beírhatod a címét ide annak a szervernek amelyhez csatlakoznál, majd azon létrehozhatsz egy fiókot.
\nHa még nincs fiókod, beírhatod annak a példánynak a címét, amelyhez csatlakoznál, majd azon létrehozhatsz egy fiókot.
\n
\nA szerver az a hely ahol a fiókadataidat tárolják, de ettől még ugyanúgy kommunikálhatsz más szervereken lévő emberekkel, mintha ugyanazon az oldalon lennétek.
\nA példány az a hely, ahol a fiókadataidat tárolják, de ettől még ugyanúgy kommunikálhatsz más példányokon lévő emberekkel, mintha ugyanazon az oldalon lennétek.
\n
\nTöbb információt találhatsz itt: <a href="https://joinmastodon.org">joinmastodon.org</a>. </string>
<string name="dialog_title_finishing_media_upload">Média feltöltés befejezése</string>
@ -198,7 +198,7 @@
<string name="notification_follow_name">Új követők</string>
<string name="notification_follow_description">Értesítések új követőkről</string>
<string name="notification_boost_name">Megtolások</string>
<string name="notification_boost_description">Értesítések posztjaid megtolása esetén</string>
<string name="notification_boost_description">Értesítések tülkjeid megtolása esetén</string>
<string name="notification_favourite_name">Kedvencek</string>
<string name="notification_favourite_description">Értesítések mikor tülkjeidet kedvencnek jelölik</string>
<string name="notification_mention_format">%s megemlített téged</string>
@ -236,7 +236,7 @@
<string name="action_lists">Listák</string>
<string name="title_lists">Listák</string>
<string name="action_remove">Törlés</string>
<string name="lock_account_label">Fiók lezárása</string>
<string name="lock_account_label">Fiók zárolása</string>
<string name="compose_save_draft">Elmented a vázlatot?</string>
<string name="send_toot_notification_title">Tülk elküldése…</string>
<string name="send_toot_notification_error_title">A tülk elküldése nem sikerült</string>
@ -433,7 +433,7 @@
<string name="action_access_scheduled_toot">Időzített tülkök</string>
<string name="action_schedule_toot">Tülk Időzítése</string>
<string name="action_reset_schedule">Visszaállítás</string>
<string name="post_lookup_error_format">Nem találjuk ezt a posztot %s</string>
<string name="post_lookup_error_format">Nem találjuk ezt a tülköt %s</string>
<string name="title_bookmarks">Könyvjelzők</string>
<string name="action_bookmark">Könyvjelzőzés</string>
<string name="action_view_bookmarks">Könyvjelzők</string>
@ -441,7 +441,7 @@
<string name="description_status_bookmarked">Könyvjelzőzve</string>
<string name="select_list_title">Lista kiválasztása</string>
<string name="list">Lista</string>
<string name="error_audio_upload_size">A hangfájlok mérete 40MB-nál kisebb kell legyen.</string>
<string name="error_audio_upload_size">A hangfájloknak kisebbnek kell lenniük, mint 40 MB.</string>
<string name="no_saved_status">Nincs egy vázlatod sem.</string>
<string name="no_scheduled_status">Nincs egy ütemezett tülköd sem.</string>
<string name="warning_scheduling_interval">A Mastodonban a legrövidebb ütemezhető időintervallum 5 perc.</string>
@ -462,7 +462,7 @@
<string name="pref_title_gradient_for_media">Színes homály mutatása rejtett médiánál</string>
<string name="pref_title_notification_filter_follow_requests">követni szeretnének</string>
<string name="dialog_mute_hide_notifications">Értesítések elrejtése</string>
<string name="dialog_block_warning">Letiltsuk @%s -t\?</string>
<string name="dialog_block_warning">Blokkolod: @%s\?</string>
<string name="dialog_mute_warning">Elnémítsuk @%s fiókot\?</string>
<string name="action_unmute_conversation">Beszélgetés némításának feloldása</string>
<string name="action_mute_conversation">Beszélgetés némítása</string>

View file

@ -415,8 +415,8 @@
<string name="notification_follow_request_name">Fylgjendabeiðnir</string>
<string name="hashtags">Myllumerki</string>
<plurals name="favs">
<item quantity="one"><b>%1$s</b> Eftirlæti</item>
<item quantity="other"><b>%1$s</b> Eftirlæti</item>
<item quantity="one"><b>%1$s</b> eftirlæti</item>
<item quantity="other"><b>%1$s</b> eftirlæti</item>
</plurals>
<plurals name="reblogs">
<item quantity="one"><b>%s</b> Endurbirting</item>
@ -438,4 +438,33 @@
<item quantity="one">%d dagur eftir</item>
<item quantity="other">%d dagar eftir</item>
</plurals>
<string name="account_note_saved">Vistað!</string>
<string name="account_note_hint">Þí eigin einkaathugasemd um þennan aðgang</string>
<string name="pref_title_hide_top_toolbar">Fela titil á verkfærastikunni efst</string>
<string name="pref_title_confirm_reblogs">Birta staðfestingarglugga áður en endurbirting fer fram</string>
<string name="pref_title_show_cards_in_timelines">Birta forskoðun tengla á tímalínum</string>
<string name="no_announcements">Það eru engar tilkynningar.</string>
<string name="pref_title_enable_swipe_for_tabs">Virkja strokuhreyfingu til að skipta milli flipa</string>
<plurals name="poll_info_people">
<item quantity="one">%s aðili</item>
<item quantity="other">%s aðilar</item>
</plurals>
<string name="add_hashtag_title">Bæta við myllumerki</string>
<string name="notification_follow_request_description">Tilkynningar um fylgjendabeiðnir</string>
<string name="pref_main_nav_position_option_bottom">Neðst</string>
<string name="pref_main_nav_position_option_top">Efst</string>
<string name="pref_main_nav_position">Aðalstaða leiðsagnar</string>
<string name="pref_title_gradient_for_media">Birta litstigla í stað falins myndefnis</string>
<string name="pref_title_notification_filter_follow_requests">beiðni um að fylgja</string>
<string name="dialog_mute_hide_notifications">Fela tilkynningar</string>
<string name="dialog_mute_warning">Þagga niður í @%s\?</string>
<string name="dialog_block_warning">Loka á @%s\?</string>
<string name="action_unmute_conversation">Hætta að þagga niður í samtölum</string>
<string name="action_mute_conversation">Þagga niður í samtölum</string>
<string name="action_unmute_domain">Afþagga %s</string>
<string name="action_mute_notifications_desc">Þagga tilkynningar frá %s</string>
<string name="action_unmute_notifications_desc">Afþagga tilkynningar frá %s</string>
<string name="action_unmute_desc">Afþagga %s</string>
<string name="notification_follow_request_format">%s bað um að fylgjast með þér</string>
<string name="title_announcements">Tilkynningar</string>
</resources>

View file

@ -482,4 +482,5 @@
<string name="action_mute_notifications_desc">Disattiva le notifiche da %s</string>
<string name="action_unmute_notifications_desc">Riattiva le notifiche da %s</string>
<string name="title_announcements">Annunci</string>
<string name="pref_title_notification_filter_follow_requests">Richieste di seguirti</string>
</resources>

View file

@ -480,4 +480,8 @@
<string name="dialog_mute_hide_notifications">Dölj aviseringar</string>
<string name="action_mute_notifications_desc">Tysta aviseringar från %s</string>
<string name="action_unmute_notifications_desc">Aktivera aviseringar från %s</string>
<string name="account_note_saved">Sparat!</string>
<string name="account_note_hint">Din privata notering om detta kontot</string>
<string name="no_announcements">Det finns inga meddelanden.</string>
<string name="title_announcements">Meddelanden</string>
</resources>

View file

@ -48,7 +48,7 @@
<string name="action_reset_schedule">Làm tươi</string>
<string name="action_search">Tìm kiếm</string>
<string name="action_edit_profile">Trang cá nhân</string>
<string name="action_view_account_preferences">Riêng bạn</string>
<string name="action_view_account_preferences">Tài khoản</string>
<string name="action_view_preferences">Cài đặt</string>
<string name="action_logout">Đăng xuất</string>
<string name="button_done">Xong</string>
@ -97,7 +97,7 @@
<string name="download_media">Tải về</string>
<string name="action_share_as">Chia sẻ với tư cách …</string>
<string name="action_open_as">Mở với tư cách %s</string>
<string name="action_copy_link">Sao chép URL</string>
<string name="action_copy_link">Chép URL</string>
<string name="download_image">Đang tải %1$s</string>
<string name="action_open_media_n">Mở tập tin #%d</string>
<string name="title_links_dialog">Links</string>
@ -131,7 +131,7 @@
<string name="action_mute">Ẩn</string>
<string name="action_share">Chia sẻ</string>
<string name="action_photo_take">Chụp hình</string>
<string name="action_add_poll">Tạo vău</string>
<string name="action_add_poll">Tạo bình chọn</string>
<string name="action_add_media">Thêm tệp</string>
<string name="action_open_in_web">Mở trong trình duyệt</string>
<string name="action_view_media">Bộ sưu tập</string>
@ -221,7 +221,7 @@
<string name="pref_title_timelines">Bảng tin</string>
<string name="pref_title_app_theme">Chủ đề</string>
<string name="pref_title_appearance_settings">Giao diện</string>
<string name="pref_title_notification_filter_poll">vău đã kết thúc</string>
<string name="pref_title_notification_filter_poll">cuộc bình chọn kết thúc</string>
<string name="pref_title_notification_filter_favourites">tút được thích</string>
<string name="pref_title_notification_filter_reblogs">tút được chia sẻ</string>
<string name="pref_title_notification_filter_follow_requests">yêu cầu theo dõi</string>
@ -236,7 +236,7 @@
<string name="pref_title_edit_notification_settings">Thông báo</string>
<string name="visibility_direct">Nhắn tin: Chỉ người được nhắc tới mới thấy</string>
<string name="visibility_private">Người theo dõi: Ai đã theo dõi mới xem được</string>
<string name="visibility_unlisted">Mở: Công khai, không hiện trên bảng tin</string>
<string name="visibility_unlisted">Riêng tư: Không hiện trên bảng tin</string>
<string name="visibility_public">Công khai: Mọi người đều có thể thấy</string>
<string name="dialog_mute_warning">Ẩn @%s\?</string>
<string name="dialog_block_warning">Chặn @%s\?</string>
@ -253,20 +253,20 @@
<string name="status_text_size_smallest">Nhỏ</string>
<string name="pref_status_text_size">Kích thức phông chữ</string>
<string name="post_privacy_followers_only">Người theo dõi</string>
<string name="post_privacy_unlisted">Mở</string>
<string name="post_privacy_unlisted">Riêng tư</string>
<string name="post_privacy_public">Công khai</string>
<string name="pref_main_nav_position_option_bottom">Dưới màn hình</string>
<string name="pref_main_nav_position_option_top">Trên màn hình</string>
<string name="pref_main_nav_position">Vị trí menu</string>
<string name="pref_failed_to_sync">Đồng bộ hoá thất bại</string>
<string name="pref_publishing">Đăng (đồng bộ với máy chủ)</string>
<string name="pref_default_media_sensitivity">Luôn đánh dấu nội dung là nhạy cảm</string>
<string name="pref_default_media_sensitivity">Tài khoản nhạy cảm</string>
<string name="pref_default_post_privacy">Trạng thái tút mặc định</string>
<string name="pref_title_http_proxy_server">HTTP proxy server</string>
<string name="pref_title_http_proxy_port">HTTP proxy port</string>
<string name="pref_title_http_proxy_enable">Bật HTTP proxy</string>
<string name="pref_title_http_proxy_settings">HTTP proxy</string>
<string name="pref_title_proxy_settings">Proxy</string>
<string name="pref_title_http_proxy_server">Máy chủ proxy</string>
<string name="pref_title_http_proxy_port">Cổng</string>
<string name="pref_title_http_proxy_enable">Bật proxy</string>
<string name="pref_title_http_proxy_settings">Dùng proxy</string>
<string name="pref_title_proxy_settings">Vượt tường lửa</string>
<string name="notification_boost_description">Thông báo khi của bạn được chia sẻ</string>
<string name="notification_boost_name">Chia sẻ</string>
<string name="notification_follow_request_description">Thông báo về lượt yêu cầu theo dõi</string>
@ -278,8 +278,8 @@
<string name="about_powered_by_tusky">Powered by Tusky</string>
<string name="about_tusky_version">Tusky %s</string>
<string name="description_account_locked">Tài khoản bị khóa</string>
<string name="notification_poll_description">Thông báo khi những vău kết thúc</string>
<string name="notification_poll_name">Vău</string>
<string name="notification_poll_description">Thông báo khi một cuộc bình chọn kết thúc</string>
<string name="notification_poll_name">Bình chọn</string>
<string name="notification_favourite_description">Thông báo khi ai đó thích tút của bạn</string>
<string name="notification_favourite_name">Lượt thích</string>
<string name="filter_dialog_whole_word">Toàn bộ câu</string>
@ -315,9 +315,9 @@
<string name="no_scheduled_status">Bạn không có tút đã lên lịch.</string>
<string name="no_saved_status">Bạn không có bản nháp nào.</string>
<string name="edit_poll">Sửa</string>
<string name="poll_new_choice_hint">Bình chọn %d</string>
<string name="poll_allow_multiple_choices">Cho phép vău nhiều bình chọn</string>
<string name="add_poll_choice">Thêm bình chọn</string>
<string name="poll_new_choice_hint">Lựa chọn %d</string>
<string name="poll_allow_multiple_choices">Cho phép chọn nhiều lựa chọn</string>
<string name="add_poll_choice">Thêm lựa chọn</string>
<string name="poll_duration_7_days">7 ngày</string>
<string name="poll_duration_3_days">3 ngày</string>
<string name="poll_duration_1_day">1 ngày</string>
@ -325,8 +325,8 @@
<string name="poll_duration_1_hour">1 giờ</string>
<string name="poll_duration_30_min">30 phút</string>
<string name="poll_duration_5_min">5 phút</string>
<string name="create_poll_title">Vău</string>
<string name="pref_title_enable_swipe_for_tabs">Vuốt để chuyển qua lại giữa các tab</string>
<string name="create_poll_title">Bình chọn</string>
<string name="pref_title_enable_swipe_for_tabs">Vuốt qua lại giữa các tab</string>
<string name="pref_title_show_notifications_filter">Hiện bộ lọc thông báo</string>
<string name="failed_search">Không thể tìm thấy</string>
<string name="title_accounts">Người</string>
@ -349,18 +349,18 @@
<plurals name="poll_timespan_days">
<item quantity="other">%d ngày nữa kết thúc</item>
</plurals>
<string name="poll_ended_created">Vău bạn tạo đã kết thúc</string>
<string name="poll_ended_voted">Vău mà bạn tham gia đã kết thúc</string>
<string name="poll_vote">Vău</string>
<string name="poll_ended_created">Cuộc bình chọn bạn tạo đã kết thúc</string>
<string name="poll_ended_voted">Cuộc bình chọn của bạn đã kết thúc</string>
<string name="poll_vote">Bình chọn</string>
<string name="poll_info_closed">Kết thúc</string>
<string name="poll_info_time_absolute">kết thúc lúc %s</string>
<plurals name="poll_info_people">
<item quantity="other">%s người</item>
</plurals>
<plurals name="poll_info_votes">
<item quantity="other">%s vău</item>
<item quantity="other">%s người</item>
</plurals>
<string name="poll_info_format"> <!-- 15 vău • 1 tiếng nữa kết thúc --> %1$s • %2$s</string>
<string name="poll_info_format"> <!-- 15 người • 1 tiếng nữa kết thúc --> %1$s • %2$s</string>
<string name="compose_preview_image_description">Mô tả cho hình %s</string>
<string name="compose_shortcut_short_label">Viết</string>
<string name="compose_shortcut_long_label">Viết tút</string>
@ -376,7 +376,7 @@
<string name="description_poll">Lượt bình chọn: %1$s, %2$s, %3$s, %4$s; %5$s</string>
<string name="description_visiblity_direct">Tin nhắn</string>
<string name="description_visiblity_private">Người theo dõi</string>
<string name="description_visiblity_unlisted">Mở</string>
<string name="description_visiblity_unlisted">Riêng tư</string>
<string name="description_visiblity_public">Công khai</string>
<string name="description_status_bookmarked">Đã lưu</string>
<string name="description_status_favourited">Đã thích</string>
@ -456,7 +456,7 @@
<string name="action_unmute_domain">Bỏ ẩn %s</string>
<string name="pref_title_hide_top_toolbar">Ẩn tiêu đề tab</string>
<string name="account_note_saved">Đã lưu!</string>
<string name="account_note_hint">Chú thích của bạn về người này</string>
<string name="account_note_hint">Ghi chú của bạn</string>
<string name="no_announcements">Chưa có thông báo.</string>
<string name="title_announcements">Thông báo</string>
<string name="title_announcements">Tin tức</string>
</resources>

View file

@ -477,8 +477,8 @@
<string name="notification_follow_request_format">%s 请求关注你</string>
<string name="pref_main_nav_position">导航栏位置</string>
<string name="pref_title_hide_top_toolbar">隐藏顶部工具栏标题</string>
<plurals name="poll_info_people">
<item quantity="one">%s 人</item>
<item quantity="other"/>
</plurals>
<string name="no_announcements">本站暂无公告。</string>
<string name="title_announcements">公告</string>
<string name="account_note_saved">已保存</string>
<string name="account_note_hint">此账号的备注</string>
</resources>

View file

@ -80,6 +80,8 @@
<item name="swipeRefreshLayoutProgressSpinnerBackgroundColor">?attr/colorSurface</item>
<item name="chipStyle">@style/Widget.MaterialComponents.Chip.Choice</item>
<item name="preferenceTheme">@style/TuskyPreferenceTheme</item>
</style>
<style name="ViewMediaActivity.AppBarLayout" parent="ThemeOverlay.AppCompat">
@ -103,6 +105,10 @@
<item name="tabIndicatorHeight">3dp</item>
</style>
<style name="TuskyPreferenceTheme" parent="@style/PreferenceThemeOverlay.v14.Material">
<item name="android:tint">?iconColor</item>
</style>
<style name="TuskyImageButton" parent="@style/Widget.MaterialComponents.Button.UnelevatedButton">
<item name="android:tint">?android:attr/textColorTertiary</item>
<item name="android:background">?attr/selectableItemBackgroundBorderless</item>

View file

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.4.20'
ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()

View file

@ -1,8 +1,8 @@
Tusky útg6.0
Tusky útg. 6
- Tímalínusíur hafa verið færðar í kjörstillingar notandaaðgangs og munu samstillast við vefþjón
- YNú geturðu haft sérsniðið myllumerki sem flipa í aðalviðmóti
- Hægt er að breyta listumk
- Hægt er að breyta listum
- Öryggi: fjarlægður stuðningur við TLS 1.0 og TLS 1.1, bætt við stuðningi við TLS 1.3 á Android 6+
- Semja-sýnin stingur núna upp á sérsniðnum tjáningartáknum þegar byrjað er að skrifa
- Ný stilling á þema "nota þema kerfis"

View file

@ -1,3 +1,3 @@
Tusky útg9.1
Tusky útg. 9.1
Þessi útgáfa tryggir samhæfni við Mastodon 3 og bætir afköst og stöðugleika.

View file

@ -1,6 +1,6 @@
Tusky v10.0
- Þú getur núna bákamerkt stöðufærslur og gert lista með bókamerkjunum þínum í Tusky.
- Þú getur núna bókamerkt stöðufærslur og gert lista með bókamerkjunum þínum í Tusky.
- Þú getur núna sett tíst á áætlun í Tusky. Athugaðu að tíminn sem þú velur þarf að vera í það minnsta efti 5 mínútur.
- Þú getur núna bætt listum á aðalskjáinn.
- Þú getur núna sent in hljóðskrár sem viðhengi í Tusky.

View file

@ -0,0 +1,10 @@
Tusky útg. 13.0
- stuðningur við minnispunkta í sniðum (Mastodon 3.2.0 eiginleiki)
- stuðningur við tilkynningar frá stjórnendum (Mastodon 3.1.0 eiginleiki)
- auðkennismynd úr völdum aðgangi birist núna í aðalverkfærastikunni
- smellt á birtingarnafn á tímalínu opnar núna notandasniðssíðu þess notanda
- hellingur að villulagfæringum og minni betrumbótum
- bættar þýðingar

View file

@ -0,0 +1,10 @@
Tusky v13.0
- support for profile notes (Mastodon 3.2.0 feature)
- support for admin announcements (Mastodon 3.1.0 feature)
- the avatar of your selected account will now be shown in the main toolbar
- clicking the display name in a timeline will now open the profile page of that user
- a lot of bug fixes and small improvements
- improved translations

View file

@ -0,0 +1,10 @@
Tusky v13.0
- 支持账号备注Mastodon 3.2.0 特性)
- 支持公告栏Mastodon 3.1.0特性)
- 当前账号的头像将在导航栏显示
- 在时间线中点击账号名称后打开该用户的资料页
- 其他许多小改进和错误修复
- 改善翻译

View file

@ -1,12 +1,12 @@
Tusky是Mastodon一个免费的开源社交网络服务器的轻量级客户端。
材料设计
实施了大多数Mastodon API
MD设计
支持大多数Mastodon API
•多帐户支持
•深色和浅色主题,可以根据一天中的时间自动切换
•草稿-编写嘟文并将其保存以备后用
•选择不同的表情符号样式
•深色和浅色主题,可以根据时间自动切换
•草稿 - 编写嘟文并将其保存以备后用
•选择不同的表情样式
•针对所有屏幕尺寸进行了优化
•完全开源-没有像Google服务这样的非自由依赖项
•完全开源 - 没有像Google服务这样的非自由依赖项
要了解有关Mastodon的更多信息请访问 https://joinmastodon.org/