Compare commits
285 Commits
v1.2.0+for
...
v1.2.3+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99f0817bdb | ||
|
|
220cd35d82 | ||
|
|
07f4ef1697 | ||
|
|
f20732ddc2 | ||
|
|
b1e0dc5843 | ||
|
|
285eb25706 | ||
|
|
ec556511e6 | ||
|
|
85c3d9f65f | ||
|
|
a7ebadf269 | ||
|
|
94c09d46c2 | ||
|
|
f6f08d176c | ||
|
|
66cdd63496 | ||
|
|
8b502b605c | ||
|
|
2c0ec28803 | ||
|
|
a9ab9cb249 | ||
|
|
961c69b525 | ||
|
|
c70f393559 | ||
|
|
9abdc174f4 | ||
|
|
2e5bfa1d9c | ||
|
|
33cbd85e19 | ||
|
|
8cb1f3f387 | ||
|
|
3f0c6fcec5 | ||
|
|
797cf893da | ||
|
|
a3564b70e1 | ||
|
|
43004307b8 | ||
|
|
acd1e4ced3 | ||
|
|
6717070f93 | ||
|
|
387499ae49 | ||
|
|
8ab140c55d | ||
|
|
914abb95dd | ||
|
|
5360c0f0f7 | ||
|
|
243d803b51 | ||
|
|
b343fe3835 | ||
|
|
3c42c1120f | ||
|
|
ad840dcef6 | ||
|
|
f73072d95e | ||
|
|
95cb9b5079 | ||
|
|
c6684d3c9b | ||
|
|
5c5989d8c0 | ||
|
|
60e92d30b0 | ||
|
|
8bf8e3f86b | ||
|
|
891ee2d06b | ||
|
|
b450bc7ae8 | ||
|
|
4ca1e0d5db | ||
|
|
859213dd9e | ||
|
|
ad2857791d | ||
|
|
497827f2e2 | ||
|
|
967e333022 | ||
|
|
8df1406006 | ||
|
|
4af42fafdc | ||
|
|
a9e6a452c1 | ||
|
|
a4a4632397 | ||
|
|
421f39e414 | ||
|
|
f8121e2dc4 | ||
|
|
b1784fc51c | ||
|
|
96db0d7de7 | ||
|
|
3837ed9cb1 | ||
|
|
2be789a43c | ||
|
|
fd8d96169a | ||
|
|
1562dc32c1 | ||
|
|
38f377ca09 | ||
|
|
cc28bba884 | ||
|
|
beb3081918 | ||
|
|
1b3c9106b5 | ||
|
|
385b91761b | ||
|
|
d7b76ed70a | ||
|
|
43600756c0 | ||
|
|
3c3e0633ad | ||
|
|
f819ad6917 | ||
|
|
2e84faa505 | ||
|
|
e7e8d13d9e | ||
|
|
a683c2cb11 | ||
|
|
addf7de316 | ||
|
|
44d4eada51 | ||
|
|
40bfdea5b1 | ||
|
|
55138c1e86 | ||
|
|
e7ad396fc6 | ||
|
|
0aef680572 | ||
|
|
6dc37d6bde | ||
|
|
60ea7cedf6 | ||
|
|
c986b10e14 | ||
|
|
d52174bd9e | ||
|
|
c65d138911 | ||
|
|
ad9bb8ad58 | ||
|
|
63e536c66c | ||
|
|
b5a08b1b98 | ||
|
|
226e2a7cdc | ||
|
|
4d7c4aed4c | ||
|
|
c9bcd000c3 | ||
|
|
b1cb4d4257 | ||
|
|
de42145f30 | ||
|
|
7bcdd6070a | ||
|
|
8a215e90d0 | ||
|
|
b736fa18bb | ||
|
|
43c19e4942 | ||
|
|
ffc18029bb | ||
|
|
b88b3d15f8 | ||
|
|
c817886a2d | ||
|
|
aae239494e | ||
|
|
b0b2daa5d5 | ||
|
|
eea2e38f1b | ||
|
|
f894ecd25b | ||
|
|
e0b6ed7103 | ||
|
|
a78e75747a | ||
|
|
3b25e367bb | ||
|
|
08b29dff3d | ||
|
|
2f2e053d26 | ||
|
|
191d582c30 | ||
|
|
8d3380ff6e | ||
|
|
ba85d18574 | ||
|
|
0f53b17515 | ||
|
|
cb9c869712 | ||
|
|
aa3d9e7b8f | ||
|
|
b3a9b5824d | ||
|
|
b6186a349f | ||
|
|
100bd4b062 | ||
|
|
7da09d9b37 | ||
|
|
f46eb07228 | ||
|
|
7627b5eb25 | ||
|
|
c710448c6b | ||
|
|
1ad270b1d6 | ||
|
|
099e253b2b | ||
|
|
66de4a5b91 | ||
|
|
41437d91d5 | ||
|
|
d33d5a6efa | ||
|
|
4f9248d040 | ||
|
|
f40c0e41f3 | ||
|
|
15fcb0e25d | ||
|
|
2dae662333 | ||
|
|
3ad46926f1 | ||
|
|
2385d102ae | ||
|
|
deeb03ff2b | ||
|
|
5c2a09e243 | ||
|
|
2473c999db | ||
|
|
ea2cc265e3 | ||
|
|
a0cd2d42cf | ||
|
|
0a17ceb984 | ||
|
|
4ef18f1f4a | ||
|
|
0de227ab9c | ||
|
|
19cb8703a6 | ||
|
|
e18567dd82 | ||
|
|
bfb3bcdbfb | ||
|
|
565cd14d88 | ||
|
|
ebc37eac75 | ||
|
|
c3702db577 | ||
|
|
e15c4fa342 | ||
|
|
8330b9f1c5 | ||
|
|
f759150982 | ||
|
|
6af177b596 | ||
|
|
657bb94975 | ||
|
|
3c946212b1 | ||
|
|
b4e80f7fca | ||
|
|
c9efc2cb2b | ||
|
|
0d62e33dc7 | ||
|
|
ac88b9e19c | ||
|
|
871dfda79e | ||
|
|
e0c2c208ae | ||
|
|
22ac112bdb | ||
|
|
afd0cca176 | ||
|
|
c083c8bce5 | ||
|
|
63bde032b3 | ||
|
|
49492c0788 | ||
|
|
b439c64add | ||
|
|
1868bfe8e3 | ||
|
|
f240a3d996 | ||
|
|
788e5bd12e | ||
|
|
a55fed4502 | ||
|
|
a8fdaf1a47 | ||
|
|
4a758bd488 | ||
|
|
2c9731ec2a | ||
|
|
eef33266fc | ||
|
|
58d2c3e5a6 | ||
|
|
9e6a355db0 | ||
|
|
0d10e09fd6 | ||
|
|
f85bb995ba | ||
|
|
268e5639f6 | ||
|
|
51809df8ca | ||
|
|
94fb676b0c | ||
|
|
a47106594b | ||
|
|
d93d66f702 | ||
|
|
b2f9f7ae54 | ||
|
|
de7b908c78 | ||
|
|
75d3c2fdce | ||
|
|
ea1b6c5835 | ||
|
|
cb7887da41 | ||
|
|
a80313ee6b | ||
|
|
e1a821bc43 | ||
|
|
924ea2d03a | ||
|
|
55270fe654 | ||
|
|
a125fab57b | ||
|
|
395ee0aa99 | ||
|
|
0f50fa6ba1 | ||
|
|
adb7df3c71 | ||
|
|
5d7bcb629b | ||
|
|
a00f1417d2 | ||
|
|
8efd7e8ebf | ||
|
|
b016d277e0 | ||
|
|
fdb39617d1 | ||
|
|
89f83fbf62 | ||
|
|
ecee9e01a6 | ||
|
|
20dc9bb8b9 | ||
|
|
2c47d0e9ed | ||
|
|
8e13d52e51 | ||
|
|
cc40198c9e | ||
|
|
290897ea41 | ||
|
|
b9e1c84304 | ||
|
|
3c44c80e2e | ||
|
|
dffa4e4594 | ||
|
|
fa2d9fec58 | ||
|
|
09c1a2cfa0 | ||
|
|
d1f90eb231 | ||
|
|
1f7d97134b | ||
|
|
79be91784d | ||
|
|
de2654def3 | ||
|
|
56343dacff | ||
|
|
0e677f8ce7 | ||
|
|
aa911896d6 | ||
|
|
c62a8635b9 | ||
|
|
4e900247c5 | ||
|
|
b3bd62bc6c | ||
|
|
8e5fd48ecd | ||
|
|
b2bca9dd2c | ||
|
|
b8c0dc3181 | ||
|
|
cccdc5292e | ||
|
|
76d77a0e7a | ||
|
|
e737f4bf9a | ||
|
|
391db2f1c9 | ||
|
|
359d61183c | ||
|
|
46fd05d88e | ||
|
|
cde22a0945 | ||
|
|
111b7e25c5 | ||
|
|
4f8d8f0c8d | ||
|
|
915b0603d0 | ||
|
|
6ec43a6f86 | ||
|
|
df93a1a845 | ||
|
|
41a70a353c | ||
|
|
8d69bcfd4b | ||
|
|
0ef30f82a7 | ||
|
|
be60e78ea6 | ||
|
|
5434325fa8 | ||
|
|
0a04c9357c | ||
|
|
075aab8074 | ||
|
|
21c4cef397 | ||
|
|
4b2fcd760a | ||
|
|
6ebe4c86af | ||
|
|
0925c8c582 | ||
|
|
9824b5fb56 | ||
|
|
78fcf31e34 | ||
|
|
eadb62d3a8 | ||
|
|
f6279fcc0c | ||
|
|
a683fdce62 | ||
|
|
b958299446 | ||
|
|
3f80be8377 | ||
|
|
ced0accde5 | ||
|
|
b454ff5ec7 | ||
|
|
45af198f32 | ||
|
|
ff374f8899 | ||
|
|
faecb3bc4b | ||
|
|
6b893fadef | ||
|
|
c328467a41 | ||
|
|
182325470b | ||
|
|
f330ad71ac | ||
|
|
ba0c064f36 | ||
|
|
8d7aaee5b9 | ||
|
|
68cba2de63 | ||
|
|
5a914f9c0e | ||
|
|
b0e6805a20 | ||
|
|
21e7e44c01 | ||
|
|
f7df4abdae | ||
|
|
7674ceefe9 | ||
|
|
4be575c534 | ||
|
|
dd0f0a7d5a | ||
|
|
759b44c224 | ||
|
|
c97a7e5158 | ||
|
|
32e2d24b15 | ||
|
|
c102aae819 | ||
|
|
bed72cb5ed | ||
|
|
f0c1046fe9 | ||
|
|
d88104d105 | ||
|
|
f3e21e5a82 | ||
|
|
a77bee8664 | ||
|
|
b5d0aed59e | ||
|
|
2440cc6af5 | ||
|
|
90114dfbe0 | ||
|
|
64b8cdf7dc |
11
.github/workflows/validate-gradle-wrapper.yml
vendored
Normal file
11
.github/workflows/validate-gradle-wrapper.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
name: Validate Gradle Wrapper
|
||||||
|
|
||||||
|
on: [pull_request, push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validation:
|
||||||
|
name: Validation
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: gradle/wrapper-validation-action@v1
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Megalodon</title>
|
<title>Megalodon</title>
|
||||||
<link rel="icon" href="mastodon/src/main/res/mipmap-mdpi/ic_launcher_round.png">
|
<link rel="icon" href="mastodon/src/main/res/mipmap-mdpi/ic_launcher_round.png">
|
||||||
<link rel="me" href="https://floss.social/@mastodon">
|
<link rel="me" href="https://floss.social/@megalodon">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body class="markdown-body">
|
<body class="markdown-body">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ buildscript {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
classpath 'com.android.tools.build:gradle:8.0.0'
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
files:
|
|
||||||
- source: /mastodon/src/main/res/values/strings.xml
|
|
||||||
translation: /mastodon/src/main/res/values-%android_code%/strings.xml
|
|
||||||
- source: /fastlane/metadata/android/en-US/*.txt
|
|
||||||
translation: /fastlane/metadata/android/%locale%/%original_file_name%
|
|
||||||
@@ -16,4 +16,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
|||||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
# Automatically convert third-party libraries to use AndroidX
|
# Automatically convert third-party libraries to use AndroidX
|
||||||
android.enableJetifier=false
|
android.enableJetifier=false
|
||||||
|
android.defaults.buildfeatures.buildconfig=true
|
||||||
|
android.nonTransitiveRClass=true
|
||||||
|
android.nonFinalResIds=false
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
7
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,7 @@
|
|||||||
#Thu Jan 13 11:33:43 MSK 2022
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStorePath=wrapper/dists
|
distributionSha256Sum=e111cb9948407e26351227dabce49822fb88c37ee72f1d1582a69c68af2e702f
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
288
gradlew
vendored
288
gradlew
vendored
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2015 the original author or authors.
|
# Copyright © 2015-2021 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@@ -17,67 +17,98 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
##
|
#
|
||||||
## Gradle start up script for UN*X
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
##
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
# Resolve links: $0 may be a link
|
||||||
PRG="$0"
|
app_path=$0
|
||||||
# Need this for relative symlinks.
|
|
||||||
while [ -h "$PRG" ] ; do
|
# Need this for daisy-chained symlinks.
|
||||||
ls=`ls -ld "$PRG"`
|
while
|
||||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
if expr "$link" : '/.*' > /dev/null; then
|
[ -h "$app_path" ]
|
||||||
PRG="$link"
|
do
|
||||||
else
|
ls=$( ls -ld "$app_path" )
|
||||||
PRG=`dirname "$PRG"`"/$link"
|
link=${ls#*' -> '}
|
||||||
fi
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
done
|
done
|
||||||
SAVED="`pwd`"
|
|
||||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
|
||||||
APP_HOME="`pwd -P`"
|
|
||||||
cd "$SAVED" >/dev/null
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
# This is normally unused
|
||||||
APP_BASE_NAME=`basename "$0"`
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD="maximum"
|
MAX_FD=maximum
|
||||||
|
|
||||||
warn () {
|
warn () {
|
||||||
echo "$*"
|
echo "$*"
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
die () {
|
die () {
|
||||||
echo
|
echo
|
||||||
echo "$*"
|
echo "$*"
|
||||||
echo
|
echo
|
||||||
exit 1
|
exit 1
|
||||||
}
|
} >&2
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
# OS specific support (must be 'true' or 'false').
|
||||||
cygwin=false
|
cygwin=false
|
||||||
msys=false
|
msys=false
|
||||||
darwin=false
|
darwin=false
|
||||||
nonstop=false
|
nonstop=false
|
||||||
case "`uname`" in
|
case "$( uname )" in #(
|
||||||
CYGWIN* )
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
cygwin=true
|
Darwin* ) darwin=true ;; #(
|
||||||
;;
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
Darwin* )
|
NONSTOP* ) nonstop=true ;;
|
||||||
darwin=true
|
|
||||||
;;
|
|
||||||
MINGW* )
|
|
||||||
msys=true
|
|
||||||
;;
|
|
||||||
NONSTOP* )
|
|
||||||
nonstop=true
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
@@ -87,9 +118,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|||||||
if [ -n "$JAVA_HOME" ] ; then
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
else
|
else
|
||||||
JAVACMD="$JAVA_HOME/bin/java"
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
fi
|
fi
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
@@ -98,7 +129,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
|||||||
location of your Java installation."
|
location of your Java installation."
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
JAVACMD="java"
|
JAVACMD=java
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
@@ -106,80 +137,109 @@ location of your Java installation."
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
# Increase the maximum file descriptors if we can.
|
||||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
MAX_FD_LIMIT=`ulimit -H -n`
|
case $MAX_FD in #(
|
||||||
if [ $? -eq 0 ] ; then
|
max*)
|
||||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
MAX_FD="$MAX_FD_LIMIT"
|
# shellcheck disable=SC3045
|
||||||
fi
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
ulimit -n $MAX_FD
|
warn "Could not query maximum file descriptor limit"
|
||||||
if [ $? -ne 0 ] ; then
|
esac
|
||||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
case $MAX_FD in #(
|
||||||
fi
|
'' | soft) :;; #(
|
||||||
else
|
*)
|
||||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
fi
|
# shellcheck disable=SC3045
|
||||||
fi
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
# For Darwin, add options to specify how the application appears in the dock
|
|
||||||
if $darwin; then
|
|
||||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
|
||||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
|
||||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
|
||||||
|
|
||||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
|
||||||
|
|
||||||
# We build the pattern for arguments to be converted via cygpath
|
|
||||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
|
||||||
SEP=""
|
|
||||||
for dir in $ROOTDIRSRAW ; do
|
|
||||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
|
||||||
SEP="|"
|
|
||||||
done
|
|
||||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
|
||||||
# Add a user-defined pattern to the cygpath arguments
|
|
||||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
|
||||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
|
||||||
fi
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
i=0
|
|
||||||
for arg in "$@" ; do
|
|
||||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
|
||||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
|
||||||
|
|
||||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
|
||||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
|
||||||
else
|
|
||||||
eval `echo args$i`="\"$arg\""
|
|
||||||
fi
|
|
||||||
i=`expr $i + 1`
|
|
||||||
done
|
|
||||||
case $i in
|
|
||||||
0) set -- ;;
|
|
||||||
1) set -- "$args0" ;;
|
|
||||||
2) set -- "$args0" "$args1" ;;
|
|
||||||
3) set -- "$args0" "$args1" "$args2" ;;
|
|
||||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
|
||||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
|
||||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
|
||||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
|
||||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
|
||||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Escape application args
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
save () {
|
# * args from the command line
|
||||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
# * the main class name
|
||||||
echo " "
|
# * -classpath
|
||||||
}
|
# * -D...appname settings
|
||||||
APP_ARGS=`save "$@"`
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command;
|
||||||
|
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||||
|
# shell script including quotes and variable substitutions, so put them in
|
||||||
|
# double quotes to make sure that they get re-expanded; and
|
||||||
|
# * put everything else in single quotes, so that it's not re-expanded.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
exec "$JAVACMD" "$@"
|
||||||
|
|||||||
15
gradlew.bat
vendored
15
gradlew.bat
vendored
@@ -14,7 +14,7 @@
|
|||||||
@rem limitations under the License.
|
@rem limitations under the License.
|
||||||
@rem
|
@rem
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
@if "%DEBUG%"=="" @echo off
|
||||||
@rem ##########################################################################
|
@rem ##########################################################################
|
||||||
@rem
|
@rem
|
||||||
@rem Gradle startup script for Windows
|
@rem Gradle startup script for Windows
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
if "%OS%"=="Windows_NT" setlocal
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
set DIRNAME=%~dp0
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
set APP_BASE_NAME=%~n0
|
set APP_BASE_NAME=%~n0
|
||||||
set APP_HOME=%DIRNAME%
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
|||||||
|
|
||||||
set JAVA_EXE=java.exe
|
set JAVA_EXE=java.exe
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|||||||
|
|
||||||
:end
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
:fail
|
:fail
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
rem the _cmd.exe /c_ return code!
|
rem the _cmd.exe /c_ return code!
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
exit /b 1
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
:mainEnd
|
:mainEnd
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ plugins {
|
|||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdk 33
|
compileSdk 33
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
@@ -10,10 +16,10 @@ android {
|
|||||||
minSdk 23
|
minSdk 23
|
||||||
targetSdk 33
|
targetSdk 33
|
||||||
versionCode 83
|
versionCode 83
|
||||||
versionName "1.2.0+fork.83"
|
versionName "1.2.3+fork.83"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
resConfigs "ar-rSA", "be-rBY", "bn-rBD", "bs-rBA", "ca-rES", "cs-rCZ", "da-rDK", "de-rDE", "el-rGR", "es-rES", "eu-rES", "fa-rIR", "fi-rFI", "fil-rPH", "fr-rFR", "ga-rIE", "gd-rGB", "gl-rES", "hi-rIN", "hr-rHR", "hu-rHU", "hy-rAM", "ig-rNG", "in-rID", "is-rIS", "it-rIT", "iw-rIL", "ja-rJP", "kab", "ko-rKR", "my-rMM", "nl-rNL", "no-rNO", "oc-rFR", "pl-rPL", "pt-rBR", "pt-rPT", "ro-rRO", "ru-rRU", "si-rLK", "sl-rSI", "sv-rSE", "th-rTH", "tr-rTR", "uk-rUA", "vi-rVN", "zh-rCN", "zh-rTW"
|
resourceConfigurations += ['ar-rSA', 'ar-rDZ', 'be-rBY', 'bn-rBD', 'bs-rBA', 'ca-rES', 'cs-rCZ', 'da-rDK', 'de-rDE', 'el-rGR', 'es-rES', 'eu-rES', 'fa-rIR', 'fi-rFI', 'fil-rPH', 'fr-rFR', 'ga-rIE', 'gd-rGB', 'gl-rES', 'hi-rIN', 'hr-rHR', 'hu-rHU', 'hy-rAM', 'ig-rNG', 'in-rID', 'is-rIS', 'it-rIT', 'iw-rIL', 'ja-rJP', 'kab', 'ko-rKR', 'my-rMM', 'nl-rNL', 'no-rNO', 'oc-rFR', 'pl-rPL', 'pt-rBR', 'pt-rPT', 'ro-rRO', 'ru-rRU', 'si-rLK', 'sl-rSI', 'sv-rSE', 'th-rTH', 'tr-rTR', 'uk-rUA', 'ur-rIN', 'vi-rVN', 'zh-rCN', 'zh-rTW']
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
@@ -49,14 +55,19 @@ android {
|
|||||||
setRoot "src/github"
|
setRoot "src/github"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lintOptions{
|
namespace 'org.joinmastodon.android'
|
||||||
checkReleaseBuilds false
|
lint {
|
||||||
abortOnError false
|
abortOnError false
|
||||||
|
checkReleaseBuilds false
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
buildConfig true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api 'androidx.annotation:annotation:1.3.0'
|
api 'androidx.annotation:annotation:1.6.0'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
|
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
|
||||||
implementation 'me.grishka.litex:recyclerview:1.2.1.1'
|
implementation 'me.grishka.litex:recyclerview:1.2.1.1'
|
||||||
implementation 'me.grishka.litex:swiperefreshlayout:1.1.0.1'
|
implementation 'me.grishka.litex:swiperefreshlayout:1.1.0.1'
|
||||||
@@ -65,7 +76,7 @@ dependencies {
|
|||||||
implementation 'me.grishka.litex:viewpager:1.0.0'
|
implementation 'me.grishka.litex:viewpager:1.0.0'
|
||||||
implementation 'me.grishka.litex:viewpager2:1.0.0'
|
implementation 'me.grishka.litex:viewpager2:1.0.0'
|
||||||
implementation 'me.grishka.appkit:appkit:1.2.7'
|
implementation 'me.grishka.appkit:appkit:1.2.7'
|
||||||
implementation 'com.google.code.gson:gson:2.8.9'
|
implementation 'com.google.code.gson:gson:2.9.0'
|
||||||
implementation 'org.jsoup:jsoup:1.14.3'
|
implementation 'org.jsoup:jsoup:1.14.3'
|
||||||
implementation 'com.squareup:otto:1.3.8'
|
implementation 'com.squareup:otto:1.3.8'
|
||||||
implementation 'de.psdev:async-otto:1.0.3'
|
implementation 'de.psdev:async-otto:1.0.3'
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="org.joinmastodon.android">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
package="org.joinmastodon.android">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||||
@@ -39,6 +38,22 @@
|
|||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".PanicResponderActivity"
|
||||||
|
android:exported="true"
|
||||||
|
android:launchMode="singleInstance"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="info.guardianproject.panic.action.TRIGGER" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".ExitActivity"
|
||||||
|
android:exported="false"
|
||||||
|
android:theme="@android:style/Theme.NoDisplay" />
|
||||||
<activity android:name=".OAuthActivity" android:exported="true" android:configChanges="orientation|screenSize" android:launchMode="singleTask">
|
<activity android:name=".OAuthActivity" android:exported="true" android:configChanges="orientation|screenSize" android:launchMode="singleTask">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
# lists.d Mastodon Blocklist (c) 2022 Greyhat Academy LICENSED UNDER: CC-BY-NC-SA 4.0
|
|
||||||
# https://raw.githubusercontent.com/greyhat-academy/lists.d/main/mastodon.domains.block.list.tsv
|
|
||||||
# This list contains domains of toxic mastodon instances
|
|
||||||
# Last-Modified: 1672044500
|
|
||||||
|
|
||||||
# gab - a neonazi social network
|
|
||||||
gab.ai
|
|
||||||
gab.com
|
|
||||||
gab.protohype.net
|
|
||||||
|
|
||||||
# consequence-free speech
|
|
||||||
social.unzensiert.to
|
|
||||||
freeatlantis.com
|
|
||||||
|
|
||||||
# reactionary bigotry and hatespeech against magrinalized groups
|
|
||||||
poa.st
|
|
||||||
freespeechextremist.com
|
|
||||||
rdrama.cc
|
|
||||||
outpoa.st
|
|
||||||
anime.website
|
|
||||||
gameliberty.club
|
|
||||||
social.byoblu.com
|
|
||||||
yggdrasil.social
|
|
||||||
smuglo.li
|
|
||||||
dogeposting.social
|
|
||||||
unsafe.space
|
|
||||||
freezepeach.xyz
|
|
||||||
|
|
||||||
# + CSAM
|
|
||||||
rojogato.com
|
|
||||||
|
|
||||||
# antivaxxer shitposting & fearmongering
|
|
||||||
shadowsocial.org
|
|
||||||
|
|
||||||
# Kiwifarms
|
|
||||||
kiwifarms.net
|
|
||||||
kiwifarms.cc
|
|
||||||
kiwifarms.is
|
|
||||||
kiwifarms.pleroma.net
|
|
||||||
|
|
||||||
|
|
||||||
# https://mastodon.art/@Curator/109649354849593592
|
|
||||||
|
|
||||||
poa.st antisemitic racist homophobic
|
|
||||||
nicecrew.digital antisemitic
|
|
||||||
beefyboys.win antisemitic racist homophobic harassment
|
|
||||||
cawfee.club antisemitic racist homophobic
|
|
||||||
comfyboy.club antisemitic racist homophobic
|
|
||||||
freespeechextremist.com racist homophobic
|
|
||||||
cum.salon racist misogynist
|
|
||||||
bae.st racist
|
|
||||||
natehiggers.online racist
|
|
||||||
rapemeat.solutions misogynist
|
|
||||||
rapist.town misogynist
|
|
||||||
rapefeminists.network misogynist
|
|
||||||
kiwifarms.cc harassment
|
|
||||||
noagendasocial.com noagenda
|
|
||||||
posting.lolicon.rocks underage
|
|
||||||
urchan.org harassment homophobic racist
|
|
||||||
ryona.agency harassment
|
|
||||||
yggdrasil.social antisemitic homophobic racist
|
|
||||||
genderheretics.xyz transphobic
|
|
||||||
baraag.net underage
|
|
||||||
lolison.top underage
|
|
||||||
shota.house underage
|
|
||||||
shota.social underage
|
|
||||||
aethy.com underage
|
|
||||||
taullo.social underage
|
|
||||||
childpawn.shop underage
|
|
||||||
posting.lolicon.rocks underage
|
|
||||||
loli.best underage
|
|
||||||
gothloli.club underage
|
|
||||||
smuglo.li underage
|
|
||||||
youjo.love underage
|
|
||||||
pedo.school underage
|
|
||||||
lolison.network underage
|
|
||||||
freak.university underage
|
|
||||||
mirr0r.city underage
|
|
||||||
xhais.love underage
|
|
||||||
refusal.biz underage
|
|
||||||
refusal.llc underage
|
|
||||||
mirr0r.city underage
|
|
||||||
nnia.space underage
|
|
||||||
ignorelist.com malicious
|
|
||||||
repl.co malicious
|
|
||||||
|
|
||||||
# custom
|
|
||||||
|
|
||||||
pawoo.net csam
|
|
||||||
|
171
mastodon/src/main/assets/blocks.txt
Normal file
171
mastodon/src/main/assets/blocks.txt
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
13bells.com
|
||||||
|
4aem.com
|
||||||
|
aethy.com
|
||||||
|
anime.website
|
||||||
|
annihilation.social
|
||||||
|
anon-kenkai.com
|
||||||
|
asbestos.cafe
|
||||||
|
bae.st
|
||||||
|
bajax.us
|
||||||
|
banepo.st
|
||||||
|
baraag.net
|
||||||
|
beefyboys.win
|
||||||
|
beepboop.ga
|
||||||
|
berserker.town
|
||||||
|
bikeshed.party
|
||||||
|
boks.moe
|
||||||
|
brainsoap.net
|
||||||
|
breastmilk.club
|
||||||
|
brighteon.social
|
||||||
|
cawfee.club
|
||||||
|
clew.lol
|
||||||
|
clubcyberia.co
|
||||||
|
collapsitarian.io
|
||||||
|
comfyboy.club
|
||||||
|
contrapointsfan.club
|
||||||
|
cum.camp
|
||||||
|
cum.salon
|
||||||
|
cybercriminal.eu
|
||||||
|
darknight-coffee.org
|
||||||
|
dembased.xyz
|
||||||
|
desupost.soy
|
||||||
|
detroitriotcity.com
|
||||||
|
eatthebugs.social
|
||||||
|
eientei.org
|
||||||
|
elementality.org
|
||||||
|
eveningzoo.club
|
||||||
|
firedragonstudios.com
|
||||||
|
firefaithfellowship.com
|
||||||
|
fluf.club
|
||||||
|
foxfam.club
|
||||||
|
freak.university
|
||||||
|
freeatlantis.com
|
||||||
|
freecumextremist.com
|
||||||
|
freedomstrike.org
|
||||||
|
freesoftwareextremist.com
|
||||||
|
freespeech.group
|
||||||
|
freespeechextremist.com
|
||||||
|
freetalklive.com
|
||||||
|
froth.zone
|
||||||
|
fulltermprivacy.com
|
||||||
|
gameliberty.club
|
||||||
|
gearlandia.haus
|
||||||
|
genderheretics.xyz
|
||||||
|
geofront.rocks
|
||||||
|
gleasonator.com
|
||||||
|
glee.li
|
||||||
|
glindr.org
|
||||||
|
goyim.app
|
||||||
|
goyslop.cafe
|
||||||
|
haeder.net
|
||||||
|
handholding.io
|
||||||
|
hidamari.apartments
|
||||||
|
hitchhiker.social
|
||||||
|
hunk.city
|
||||||
|
iddqd.social
|
||||||
|
intkos.link
|
||||||
|
justicewarrior.social
|
||||||
|
kawa-kun.com
|
||||||
|
kitsunemimi.club
|
||||||
|
kiwifarms.cc
|
||||||
|
kompost.cz
|
||||||
|
kurosawa.moe
|
||||||
|
leafposter.club
|
||||||
|
leftychan.net
|
||||||
|
lewdieheaven.com
|
||||||
|
liberdon.com
|
||||||
|
ligma.pro
|
||||||
|
lizards.live
|
||||||
|
lolicon.rocks
|
||||||
|
lolison.top
|
||||||
|
lovingexpressions.net
|
||||||
|
lucasvl.nl
|
||||||
|
mahodou.moe
|
||||||
|
makemysarcophagus.com
|
||||||
|
maladaptive.art
|
||||||
|
masochi.st
|
||||||
|
mastinator.com
|
||||||
|
merovingian.club
|
||||||
|
midwaytrades.com
|
||||||
|
mirr0r.city
|
||||||
|
moa.st
|
||||||
|
mouse.services
|
||||||
|
mugicha.club
|
||||||
|
narrativerry.xyz
|
||||||
|
natehiggers.online
|
||||||
|
neckbeard.xyz
|
||||||
|
needs.vodka
|
||||||
|
neenster.org
|
||||||
|
nicecrew.digital
|
||||||
|
nnia.space
|
||||||
|
noagendasocial.com
|
||||||
|
noagendasocial.nl
|
||||||
|
noagendatube.com
|
||||||
|
nobodyhasthe.biz
|
||||||
|
nukem.biz
|
||||||
|
obo.sh
|
||||||
|
onionfarms.org
|
||||||
|
outpoa.st
|
||||||
|
pawlicker.com
|
||||||
|
pawoo.net
|
||||||
|
pedo.school
|
||||||
|
piazza.today
|
||||||
|
pibvt.net
|
||||||
|
pieville.net
|
||||||
|
pisskey.io
|
||||||
|
plagu.ee
|
||||||
|
pmth.us
|
||||||
|
poa.st
|
||||||
|
poast.org
|
||||||
|
poast.tv
|
||||||
|
poster.place
|
||||||
|
prospeech.space
|
||||||
|
quodverum.com
|
||||||
|
rakket.app
|
||||||
|
rapemeat.solutions
|
||||||
|
rdrama.cc
|
||||||
|
rebelbase.site
|
||||||
|
retardedniggers.forsale
|
||||||
|
rojogato.com
|
||||||
|
ryona.agency
|
||||||
|
schwartzwelt.xyz
|
||||||
|
seal.cafe
|
||||||
|
shigusegubu.club
|
||||||
|
shitpost.cloud
|
||||||
|
shitposter.club
|
||||||
|
shota.house
|
||||||
|
silliness.observer
|
||||||
|
skinheads.eu
|
||||||
|
skinheads.io
|
||||||
|
skinheads.social
|
||||||
|
skinheads.uk
|
||||||
|
skippers-bin.com
|
||||||
|
skyshanty.xyz
|
||||||
|
slash.cl
|
||||||
|
sleepy.cafe
|
||||||
|
smuglo.li
|
||||||
|
sneed.social
|
||||||
|
sonichu.com
|
||||||
|
spinster.xyz
|
||||||
|
springbo.cc
|
||||||
|
starnix.network
|
||||||
|
stereophonic.space
|
||||||
|
strelizia.net
|
||||||
|
syspxl.xyz
|
||||||
|
tastingtraffic.net
|
||||||
|
teci.world
|
||||||
|
theapex.social
|
||||||
|
thepostearthdestination.com
|
||||||
|
tkammer.de
|
||||||
|
trumpislovetrumpis.life
|
||||||
|
truthsocial.co.in
|
||||||
|
urchan.org
|
||||||
|
varishangout.net
|
||||||
|
whinge.house
|
||||||
|
whinge.town
|
||||||
|
wideboys.org
|
||||||
|
wolfgirl.bar
|
||||||
|
xn--p1abe3d.xn--80asehdb
|
||||||
|
yggdrasil.social
|
||||||
|
youjo.love
|
||||||
|
zztails.gay
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class ExitActivity extends Activity {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
finishAndRemoveTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void exit(Context context) {
|
||||||
|
Intent intent = new Intent(context, ExitActivity.class);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
context.startActivity(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ import org.joinmastodon.android.api.session.AccountSession;
|
|||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.ComposeFragment;
|
import org.joinmastodon.android.fragments.ComposeFragment;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
import org.jsoup.internal.StringUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -51,9 +52,15 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
|||||||
String subject = "";
|
String subject = "";
|
||||||
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
|
if (intent.hasExtra(Intent.EXTRA_SUBJECT)) {
|
||||||
subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
|
subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
|
||||||
if (!subject.isBlank()) builder.append(subject).append("\n\n");
|
if (!StringUtil.isBlank(subject)) builder.append(subject).append("\n\n");
|
||||||
|
}
|
||||||
|
if (intent.hasExtra(Intent.EXTRA_TEXT)) {
|
||||||
|
String extra = intent.getStringExtra(Intent.EXTRA_TEXT);
|
||||||
|
if (!StringUtil.isBlank(extra)) {
|
||||||
|
if (extra.startsWith(subject)) extra = extra.substring(subject.length()).trim();
|
||||||
|
builder.append(extra).append("\n\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (intent.hasExtra(Intent.EXTRA_TEXT)) builder.append(intent.getStringExtra(Intent.EXTRA_TEXT)).append("\n");
|
|
||||||
String text=builder.toString();
|
String text=builder.toString();
|
||||||
List<Uri> mediaUris;
|
List<Uri> mediaUris;
|
||||||
if(Intent.ACTION_SEND.equals(intent.getAction())){
|
if(Intent.ACTION_SEND.equals(intent.getAction())){
|
||||||
@@ -80,8 +87,7 @@ public class ExternalShareActivity extends FragmentStackActivity{
|
|||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
if(!TextUtils.isEmpty(text))
|
if(!TextUtils.isEmpty(text))
|
||||||
args.putString("prefilledText", text);
|
args.putString("prefilledText", text);
|
||||||
if(!subject.isBlank())
|
args.putInt("selectionStart", StringUtil.isBlank(subject) ? 0 : subject.length());
|
||||||
args.putInt("selectionEnd", subject.length());
|
|
||||||
if(mediaUris!=null && !mediaUris.isEmpty())
|
if(mediaUris!=null && !mediaUris.isEmpty())
|
||||||
args.putParcelableArrayList("mediaAttachments", toArrayList(mediaUris));
|
args.putParcelableArrayList("mediaAttachments", toArrayList(mediaUris));
|
||||||
Fragment fragment=new ComposeFragment();
|
Fragment fragment=new ComposeFragment();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.content.SharedPreferences;
|
|||||||
import com.google.gson.JsonSyntaxException;
|
import com.google.gson.JsonSyntaxException;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.TimelineDefinition;
|
import org.joinmastodon.android.model.TimelineDefinition;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
@@ -46,16 +47,20 @@ public class GlobalUserPreferences{
|
|||||||
public static boolean autoHideFab;
|
public static boolean autoHideFab;
|
||||||
public static boolean replyLineAboveHeader;
|
public static boolean replyLineAboveHeader;
|
||||||
public static boolean compactReblogReplyLine;
|
public static boolean compactReblogReplyLine;
|
||||||
|
public static boolean confirmBeforeReblog;
|
||||||
public static String publishButtonText;
|
public static String publishButtonText;
|
||||||
public static ThemePreference theme;
|
public static ThemePreference theme;
|
||||||
public static ColorPreference color;
|
public static ColorPreference color;
|
||||||
|
|
||||||
private final static Type recentLanguagesType = new TypeToken<Map<String, List<String>>>() {}.getType();
|
private final static Type recentLanguagesType = new TypeToken<Map<String, List<String>>>() {}.getType();
|
||||||
private final static Type pinnedTimelinesType = new TypeToken<Map<String, List<TimelineDefinition>>>() {}.getType();
|
private final static Type pinnedTimelinesType = new TypeToken<Map<String, List<TimelineDefinition>>>() {}.getType();
|
||||||
|
private final static Type accountsDefaultContentTypesType = new TypeToken<Map<String, ContentType>>() {}.getType();
|
||||||
public static Map<String, List<String>> recentLanguages;
|
public static Map<String, List<String>> recentLanguages;
|
||||||
public static Map<String, List<TimelineDefinition>> pinnedTimelines;
|
public static Map<String, List<TimelineDefinition>> pinnedTimelines;
|
||||||
public static Set<String> accountsWithLocalOnlySupport;
|
public static Set<String> accountsWithLocalOnlySupport;
|
||||||
public static Set<String> accountsInGlitchMode;
|
public static Set<String> accountsInGlitchMode;
|
||||||
|
public static Set<String> accountsWithContentTypesEnabled;
|
||||||
|
public static Map<String, ContentType> accountsDefaultContentTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pleroma
|
* Pleroma
|
||||||
@@ -102,6 +107,7 @@ public class GlobalUserPreferences{
|
|||||||
autoHideFab=prefs.getBoolean("autoHideFab", true);
|
autoHideFab=prefs.getBoolean("autoHideFab", true);
|
||||||
replyLineAboveHeader=prefs.getBoolean("replyLineAboveHeader", true);
|
replyLineAboveHeader=prefs.getBoolean("replyLineAboveHeader", true);
|
||||||
compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true);
|
compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true);
|
||||||
|
confirmBeforeReblog=prefs.getBoolean("confirmBeforeReblog", false);
|
||||||
publishButtonText=prefs.getString("publishButtonText", "");
|
publishButtonText=prefs.getString("publishButtonText", "");
|
||||||
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
|
||||||
recentLanguages=fromJson(prefs.getString("recentLanguages", null), recentLanguagesType, new HashMap<>());
|
recentLanguages=fromJson(prefs.getString("recentLanguages", null), recentLanguagesType, new HashMap<>());
|
||||||
@@ -109,6 +115,8 @@ public class GlobalUserPreferences{
|
|||||||
accountsWithLocalOnlySupport=prefs.getStringSet("accountsWithLocalOnlySupport", new HashSet<>());
|
accountsWithLocalOnlySupport=prefs.getStringSet("accountsWithLocalOnlySupport", new HashSet<>());
|
||||||
accountsInGlitchMode=prefs.getStringSet("accountsInGlitchMode", new HashSet<>());
|
accountsInGlitchMode=prefs.getStringSet("accountsInGlitchMode", new HashSet<>());
|
||||||
replyVisibility=prefs.getString("replyVisibility", null);
|
replyVisibility=prefs.getString("replyVisibility", null);
|
||||||
|
accountsWithContentTypesEnabled=prefs.getStringSet("accountsWithContentTypesEnabled", new HashSet<>());
|
||||||
|
accountsDefaultContentTypes=fromJson(prefs.getString("accountsDefaultContentTypes", null), accountsDefaultContentTypesType, new HashMap<>());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.PINK.name()));
|
color=ColorPreference.valueOf(prefs.getString("color", ColorPreference.PINK.name()));
|
||||||
@@ -148,6 +156,7 @@ public class GlobalUserPreferences{
|
|||||||
.putString("publishButtonText", publishButtonText)
|
.putString("publishButtonText", publishButtonText)
|
||||||
.putBoolean("bottomEncoding", bottomEncoding)
|
.putBoolean("bottomEncoding", bottomEncoding)
|
||||||
.putBoolean("replyLineAboveHeader", replyLineAboveHeader)
|
.putBoolean("replyLineAboveHeader", replyLineAboveHeader)
|
||||||
|
.putBoolean("confirmBeforeReblog", confirmBeforeReblog)
|
||||||
.putInt("theme", theme.ordinal())
|
.putInt("theme", theme.ordinal())
|
||||||
.putString("color", color.name())
|
.putString("color", color.name())
|
||||||
.putString("recentLanguages", gson.toJson(recentLanguages))
|
.putString("recentLanguages", gson.toJson(recentLanguages))
|
||||||
@@ -155,6 +164,8 @@ public class GlobalUserPreferences{
|
|||||||
.putStringSet("accountsWithLocalOnlySupport", accountsWithLocalOnlySupport)
|
.putStringSet("accountsWithLocalOnlySupport", accountsWithLocalOnlySupport)
|
||||||
.putStringSet("accountsInGlitchMode", accountsInGlitchMode)
|
.putStringSet("accountsInGlitchMode", accountsInGlitchMode)
|
||||||
.putString("replyVisibility", replyVisibility)
|
.putString("replyVisibility", replyVisibility)
|
||||||
|
.putStringSet("accountsWithContentTypesEnabled", accountsWithContentTypesEnabled)
|
||||||
|
.putString("accountsDefaultContentTypes", gson.toJson(accountsDefaultContentTypes))
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package org.joinmastodon.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.requests.oauth.RevokeOauthToken;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
|
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
|
||||||
|
|
||||||
|
public class PanicResponderActivity extends Activity {
|
||||||
|
public static final String PANIC_TRIGGER_ACTION = "info.guardianproject.panic.action.TRIGGER";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if (intent != null && PANIC_TRIGGER_ACTION.equals(intent.getAction())) {
|
||||||
|
AccountSessionManager.getInstance().getLoggedInAccounts().forEach(accountSession -> logOut(accountSession.getID()));
|
||||||
|
ExitActivity.exit(this);
|
||||||
|
}
|
||||||
|
finishAndRemoveTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logOut(String accountID){
|
||||||
|
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||||
|
new RevokeOauthToken(session.app.clientId, session.app.clientSecret, session.token.accessToken)
|
||||||
|
.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Object result){
|
||||||
|
onLoggedOut(accountID);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
onLoggedOut(accountID);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.exec(accountID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onLoggedOut(String accountID){
|
||||||
|
AccountSessionManager.getInstance().removeAccount(accountID);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,10 +74,8 @@ public class CacheController{
|
|||||||
int flags=cursor.getInt(1);
|
int flags=cursor.getInt(1);
|
||||||
status.hasGapAfter=((flags & POST_FLAG_GAP_AFTER)!=0);
|
status.hasGapAfter=((flags & POST_FLAG_GAP_AFTER)!=0);
|
||||||
newMaxID=status.id;
|
newMaxID=status.id;
|
||||||
for(Filter filter:filters){
|
if (!new StatusFilterPredicate(filters, Filter.FilterContext.HOME).test(status))
|
||||||
if(filter.matches(status))
|
continue outer;
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
result.add(status);
|
result.add(status);
|
||||||
}while(cursor.moveToNext());
|
}while(cursor.moveToNext());
|
||||||
String _newMaxID=newMaxID;
|
String _newMaxID=newMaxID;
|
||||||
@@ -92,7 +90,7 @@ public class CacheController{
|
|||||||
.setCallback(new Callback<>(){
|
.setCallback(new Callback<>(){
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Status> result){
|
public void onSuccess(List<Status> result){
|
||||||
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(new StatusFilterPredicate(filters)).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(new StatusFilterPredicate(filters, Filter.FilterContext.HOME)).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
||||||
putHomeTimeline(result, maxID==null);
|
putHomeTimeline(result, maxID==null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,10 +146,8 @@ public class CacheController{
|
|||||||
ntf.postprocess();
|
ntf.postprocess();
|
||||||
newMaxID=ntf.id;
|
newMaxID=ntf.id;
|
||||||
if(ntf.status!=null){
|
if(ntf.status!=null){
|
||||||
for(Filter filter:filters){
|
if (!new StatusFilterPredicate(filters, Filter.FilterContext.NOTIFICATIONS).test(ntf.status))
|
||||||
if(filter.matches(ntf.status))
|
continue outer;
|
||||||
continue outer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result.add(ntf);
|
result.add(ntf);
|
||||||
}while(cursor.moveToNext());
|
}while(cursor.moveToNext());
|
||||||
@@ -170,11 +166,7 @@ public class CacheController{
|
|||||||
public void onSuccess(List<Notification> result){
|
public void onSuccess(List<Notification> result){
|
||||||
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(ntf->{
|
callback.onSuccess(new CacheablePaginatedResponse<>(result.stream().filter(ntf->{
|
||||||
if(ntf.status!=null){
|
if(ntf.status!=null){
|
||||||
for(Filter filter:filters){
|
return new StatusFilterPredicate(filters, Filter.FilterContext.NOTIFICATIONS).test(ntf.status);
|
||||||
if(filter.matches(ntf.status)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
}).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id, false));
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@@ -51,7 +52,9 @@ public class MastodonAPIController{
|
|||||||
.registerTypeAdapter(Status.class, new Status.StatusDeserializer())
|
.registerTypeAdapter(Status.class, new Status.StatusDeserializer())
|
||||||
.create();
|
.create();
|
||||||
private static WorkerThread thread=new WorkerThread("MastodonAPIController");
|
private static WorkerThread thread=new WorkerThread("MastodonAPIController");
|
||||||
private static OkHttpClient httpClient=new OkHttpClient.Builder().build();
|
private static OkHttpClient httpClient=new OkHttpClient.Builder()
|
||||||
|
.readTimeout(5, TimeUnit.MINUTES)
|
||||||
|
.build();
|
||||||
|
|
||||||
private AccountSession session;
|
private AccountSession session;
|
||||||
private static List<String> badDomains = new ArrayList<>();
|
private static List<String> badDomains = new ArrayList<>();
|
||||||
@@ -60,7 +63,7 @@ public class MastodonAPIController{
|
|||||||
thread.start();
|
thread.start();
|
||||||
try {
|
try {
|
||||||
final BufferedReader reader = new BufferedReader(new InputStreamReader(
|
final BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||||
MastodonApp.context.getAssets().open("blocks.tsv")
|
MastodonApp.context.getAssets().open("blocks.txt")
|
||||||
));
|
));
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
@@ -91,7 +94,7 @@ public class MastodonAPIController{
|
|||||||
Request.Builder builder=new Request.Builder()
|
Request.Builder builder=new Request.Builder()
|
||||||
.url(req.getURL().toString())
|
.url(req.getURL().toString())
|
||||||
.method(req.getMethod(), req.getRequestBody())
|
.method(req.getMethod(), req.getRequestBody())
|
||||||
.header("User-Agent", "MastodonAndroid/"+BuildConfig.VERSION_NAME);
|
.header("User-Agent", "MegalodonAndroid/"+BuildConfig.VERSION_NAME);
|
||||||
|
|
||||||
String token=null;
|
String token=null;
|
||||||
if(session!=null)
|
if(session!=null)
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import android.view.View;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
|
||||||
|
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
|
||||||
public class MastodonErrorResponse extends ErrorResponse{
|
public class MastodonErrorResponse extends ErrorResponse{
|
||||||
@@ -22,7 +20,7 @@ public class MastodonErrorResponse extends ErrorResponse{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindErrorView(View view){
|
public void bindErrorView(View view){
|
||||||
TextView text=view.findViewById(R.id.error_text);
|
TextView text=view.findViewById(me.grishka.appkit.R.id.error_text);
|
||||||
text.setText(error);
|
text.setText(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.joinmastodon.android.api.requests.statuses;
|
package org.joinmastodon.android.api.requests.statuses;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.ScheduledStatus;
|
import org.joinmastodon.android.model.ScheduledStatus;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.model.StatusPrivacy;
|
import org.joinmastodon.android.model.StatusPrivacy;
|
||||||
@@ -46,6 +47,7 @@ public class CreateStatus extends MastodonAPIRequest<Status>{
|
|||||||
public String language;
|
public String language;
|
||||||
|
|
||||||
public String quoteId;
|
public String quoteId;
|
||||||
|
public ContentType contentType;
|
||||||
|
|
||||||
public static class Poll{
|
public static class Poll{
|
||||||
public ArrayList<String> options=new ArrayList<>();
|
public ArrayList<String> options=new ArrayList<>();
|
||||||
|
|||||||
@@ -2,17 +2,22 @@ package org.joinmastodon.android.api.requests.statuses;
|
|||||||
|
|
||||||
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
import org.joinmastodon.android.api.AllFieldsAreRequired;
|
||||||
import org.joinmastodon.android.api.MastodonAPIRequest;
|
import org.joinmastodon.android.api.MastodonAPIRequest;
|
||||||
|
import org.joinmastodon.android.api.RequiredField;
|
||||||
import org.joinmastodon.android.model.BaseModel;
|
import org.joinmastodon.android.model.BaseModel;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
|
|
||||||
public class GetStatusSourceText extends MastodonAPIRequest<GetStatusSourceText.Response>{
|
public class GetStatusSourceText extends MastodonAPIRequest<GetStatusSourceText.Response>{
|
||||||
public GetStatusSourceText(String id){
|
public GetStatusSourceText(String id){
|
||||||
super(HttpMethod.GET, "/statuses/"+id+"/source", Response.class);
|
super(HttpMethod.GET, "/statuses/"+id+"/source", Response.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllFieldsAreRequired
|
|
||||||
public static class Response extends BaseModel{
|
public static class Response extends BaseModel{
|
||||||
|
@RequiredField
|
||||||
public String id;
|
public String id;
|
||||||
|
@RequiredField
|
||||||
public String text;
|
public String text;
|
||||||
|
@RequiredField
|
||||||
public String spoilerText;
|
public String spoilerText;
|
||||||
|
public ContentType contentType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ package org.joinmastodon.android.fragments;
|
|||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.TranslateAnimation;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
|
import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
|
||||||
@@ -64,7 +60,12 @@ public class AccountTimelineFragment extends StatusListFragment{
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Status> result){
|
public void onSuccess(List<Status> result){
|
||||||
if(getActivity()==null) return;
|
if(getActivity()==null) return;
|
||||||
result=result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.ACCOUNT)).collect(Collectors.toList());
|
AccountSessionManager asm = AccountSessionManager.getInstance();
|
||||||
|
result=result.stream().filter(status -> {
|
||||||
|
// don't hide own posts in own profile
|
||||||
|
if (asm.isSelf(accountID, user) && asm.isSelf(accountID, status.account)) return true;
|
||||||
|
else return new StatusFilterPredicate(accountID, getFilterContext()).test(status);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
onDataLoaded(result, !result.isEmpty());
|
onDataLoaded(result, !result.isEmpty());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -122,4 +123,10 @@ public class AccountTimelineFragment extends StatusListFragment{
|
|||||||
protected void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
|
protected void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.ACCOUNT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
|
|||||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
||||||
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
|
import org.joinmastodon.android.ui.utils.MediaAttachmentViewController;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.ui.views.MediaGridLayout;
|
|
||||||
import org.joinmastodon.android.utils.TypedObjectPool;
|
import org.joinmastodon.android.utils.TypedObjectPool;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -69,7 +68,7 @@ import me.grishka.appkit.utils.BindableViewHolder;
|
|||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
import me.grishka.appkit.views.UsableRecyclerView;
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
public abstract class BaseStatusListFragment<T extends DisplayItemsParent> extends RecyclerFragment<T> implements PhotoViewerHost, ScrollableToTop{
|
public abstract class BaseStatusListFragment<T extends DisplayItemsParent> extends RecyclerFragment<T> implements PhotoViewerHost, ScrollableToTop, HasFab{
|
||||||
protected ArrayList<StatusDisplayItem> displayItems=new ArrayList<>();
|
protected ArrayList<StatusDisplayItem> displayItems=new ArrayList<>();
|
||||||
protected DisplayItemsAdapter adapter;
|
protected DisplayItemsAdapter adapter;
|
||||||
protected String accountID;
|
protected String accountID;
|
||||||
@@ -83,16 +82,17 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
|
|
||||||
public BaseStatusListFragment(){
|
public BaseStatusListFragment(){
|
||||||
super(20);
|
super(20);
|
||||||
if (withComposeButton()) setListLayoutId(R.layout.recycler_fragment_with_fab);
|
if (wantsComposeButton()) setListLayoutId(R.layout.recycler_fragment_with_fab);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
UiUtils.loadMaxWidth(getContext());
|
||||||
if(GlobalUserPreferences.disableMarquee){
|
if(GlobalUserPreferences.disableMarquee){
|
||||||
setTitleMarqueeEnabled(false);
|
setTitleMarqueeEnabled(false);
|
||||||
setSubtitleMarqueeEnabled(false);
|
setSubtitleMarqueeEnabled(false);
|
||||||
@@ -101,8 +101,6 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
setRetainInstance(true);
|
setRetainInstance(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected RecyclerView.Adapter getAdapter(){
|
protected RecyclerView.Adapter getAdapter(){
|
||||||
return adapter=new DisplayItemsAdapter();
|
return adapter=new DisplayItemsAdapter();
|
||||||
@@ -270,37 +268,59 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable View getFab() {
|
||||||
|
if (getParentFragment() instanceof HasFab l) return l.getFab();
|
||||||
|
else return fab;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showFab() {
|
||||||
|
View fab = getFab();
|
||||||
|
if (fab == null || fab.getVisibility() == View.VISIBLE) return;
|
||||||
|
fab.setVisibility(View.VISIBLE);
|
||||||
|
TranslateAnimation animate = new TranslateAnimation(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
fab.getHeight() * 2,
|
||||||
|
0);
|
||||||
|
animate.setDuration(300);
|
||||||
|
fab.startAnimation(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideFab() {
|
||||||
|
View fab = getFab();
|
||||||
|
if (fab == null || fab.getVisibility() != View.VISIBLE) return;
|
||||||
|
TranslateAnimation animate = new TranslateAnimation(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
fab.getHeight() * 2);
|
||||||
|
animate.setDuration(300);
|
||||||
|
fab.startAnimation(animate);
|
||||||
|
fab.setVisibility(View.INVISIBLE);
|
||||||
|
scrollDiff = 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
fab=view.findViewById(R.id.fab);
|
fab=view.findViewById(R.id.fab);
|
||||||
|
|
||||||
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
|
list.addOnScrollListener(new RecyclerView.OnScrollListener(){
|
||||||
@Override
|
@Override
|
||||||
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
|
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy){
|
||||||
if(currentPhotoViewer!=null)
|
if(currentPhotoViewer!=null)
|
||||||
currentPhotoViewer.offsetView(-dx, -dy);
|
currentPhotoViewer.offsetView(-dx, -dy);
|
||||||
|
|
||||||
|
View fab = getFab();
|
||||||
if (fab!=null && GlobalUserPreferences.autoHideFab) {
|
if (fab!=null && GlobalUserPreferences.autoHideFab) {
|
||||||
if (dy > 0 && fab.getVisibility() == View.VISIBLE) {
|
if (dy > 0 && fab.getVisibility() == View.VISIBLE) {
|
||||||
TranslateAnimation animate = new TranslateAnimation(
|
hideFab();
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
fab.getHeight() * 2);
|
|
||||||
animate.setDuration(300);
|
|
||||||
fab.startAnimation(animate);
|
|
||||||
fab.setVisibility(View.INVISIBLE);
|
|
||||||
scrollDiff = 0;
|
|
||||||
} else if (dy < 0 && fab.getVisibility() != View.VISIBLE) {
|
} else if (dy < 0 && fab.getVisibility() != View.VISIBLE) {
|
||||||
if (list.getChildAt(0).getTop() == 0 || scrollDiff > 400) {
|
if (list.getChildAt(0).getTop() == 0 || scrollDiff > 400) {
|
||||||
fab.setVisibility(View.VISIBLE);
|
showFab();
|
||||||
TranslateAnimation animate = new TranslateAnimation(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
fab.getHeight() * 2,
|
|
||||||
0);
|
|
||||||
animate.setDuration(300);
|
|
||||||
fab.startAnimation(animate);
|
|
||||||
scrollDiff = 0;
|
scrollDiff = 0;
|
||||||
} else {
|
} else {
|
||||||
scrollDiff += Math.abs(dy);
|
scrollDiff += Math.abs(dy);
|
||||||
@@ -343,10 +363,12 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
((UsableRecyclerView) list).setIncludeMarginsInItemHitbox(true);
|
((UsableRecyclerView) list).setIncludeMarginsInItemHitbox(true);
|
||||||
updateToolbar();
|
updateToolbar();
|
||||||
|
|
||||||
if (withComposeButton()) {
|
if (wantsComposeButton() && !getArguments().getBoolean("__disable_fab", false)) {
|
||||||
fab.setVisibility(View.VISIBLE);
|
fab.setVisibility(View.VISIBLE);
|
||||||
fab.setOnClickListener(this::onFabClick);
|
fab.setOnClickListener(this::onFabClick);
|
||||||
fab.setOnLongClickListener(this::onFabLongClick);
|
fab.setOnLongClickListener(this::onFabLongClick);
|
||||||
|
} else if (fab != null) {
|
||||||
|
fab.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,13 +677,13 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
currentPhotoViewer.onPause();
|
currentPhotoViewer.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onFabClick(View v){
|
public void onFabClick(View v){
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
Nav.go(getActivity(), ComposeFragment.class, args);
|
Nav.go(getActivity(), ComposeFragment.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean onFabLongClick(View v) {
|
public boolean onFabLongClick(View v) {
|
||||||
return UiUtils.pickAccountForCompose(getActivity(), accountID);
|
return UiUtils.pickAccountForCompose(getActivity(), accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -758,7 +780,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
|||||||
if(!imgHolder.getItem().status.spoilerRevealed){
|
if(!imgHolder.getItem().status.spoilerRevealed){
|
||||||
if(TextUtils.isEmpty(imgHolder.getItem().status.spoilerText)){
|
if(TextUtils.isEmpty(imgHolder.getItem().status.spoilerText)){
|
||||||
int listWidth=getListWidthForMediaLayout();
|
int listWidth=getListWidthForMediaLayout();
|
||||||
int width=Math.min(listWidth, V.dp(MediaGridLayout.MAX_WIDTH));
|
int width=Math.min(listWidth, UiUtils.MAX_WIDTH);
|
||||||
if(currentMediaHiddenLayoutsWidth!=width)
|
if(currentMediaHiddenLayoutsWidth!=width)
|
||||||
rebuildMediaHiddenLayouts(width-V.dp(32));
|
rebuildMediaHiddenLayouts(width-V.dp(32));
|
||||||
c.save();
|
c.save();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.app.Activity;
|
|||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetBookmarkedStatuses;
|
import org.joinmastodon.android.api.requests.statuses.GetBookmarkedStatuses;
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
|
||||||
@@ -35,4 +36,9 @@ public class BookmarkedStatusListFragment extends StatusListFragment{
|
|||||||
})
|
})
|
||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.ACCOUNT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ import org.joinmastodon.android.events.StatusCreatedEvent;
|
|||||||
import org.joinmastodon.android.events.StatusUpdatedEvent;
|
import org.joinmastodon.android.events.StatusUpdatedEvent;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Attachment;
|
import org.joinmastodon.android.model.Attachment;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.Emoji;
|
import org.joinmastodon.android.model.Emoji;
|
||||||
import org.joinmastodon.android.model.EmojiCategory;
|
import org.joinmastodon.android.model.EmojiCategory;
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
@@ -179,8 +180,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
private int charCount, charLimit, trimmedCharCount;
|
private int charCount, charLimit, trimmedCharCount;
|
||||||
|
|
||||||
private Button publishButton, languageButton, scheduleTimeBtn, draftsBtn;
|
private Button publishButton, languageButton, scheduleTimeBtn, draftsBtn;
|
||||||
private PopupMenu languagePopup, visibilityPopup, draftOptionsPopup;
|
private PopupMenu languagePopup, contentTypePopup, visibilityPopup, draftOptionsPopup;
|
||||||
private ImageButton mediaBtn, pollBtn, emojiBtn, spoilerBtn, visibilityBtn, scheduleDraftDismiss;
|
private ImageButton mediaBtn, pollBtn, emojiBtn, spoilerBtn, visibilityBtn, scheduleDraftDismiss, contentTypeBtn;
|
||||||
private ImageView sensitiveIcon;
|
private ImageView sensitiveIcon;
|
||||||
private ComposeMediaLayout attachmentsView;
|
private ComposeMediaLayout attachmentsView;
|
||||||
private TextView replyText;
|
private TextView replyText;
|
||||||
@@ -234,6 +235,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
private Runnable updateUploadEtaRunnable;
|
private Runnable updateUploadEtaRunnable;
|
||||||
|
|
||||||
private String language, encoding;
|
private String language, encoding;
|
||||||
|
private ContentType contentType;
|
||||||
private MastodonLanguage.LanguageResolver languageResolver;
|
private MastodonLanguage.LanguageResolver languageResolver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -242,6 +244,12 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
setRetainInstance(true);
|
setRetainInstance(true);
|
||||||
|
|
||||||
accountID=getArguments().getString("account");
|
accountID=getArguments().getString("account");
|
||||||
|
contentType = GlobalUserPreferences.accountsDefaultContentTypes.get(accountID);
|
||||||
|
if (contentType == null && GlobalUserPreferences.accountsWithContentTypesEnabled.contains(accountID)) {
|
||||||
|
// if formatting is enabled, use plain to avoid confusing unspecified default setting
|
||||||
|
contentType = ContentType.PLAIN;
|
||||||
|
}
|
||||||
|
|
||||||
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
AccountSession session=AccountSessionManager.getInstance().getAccount(accountID);
|
||||||
self=session.self;
|
self=session.self;
|
||||||
instanceDomain=session.domain;
|
instanceDomain=session.domain;
|
||||||
@@ -330,6 +338,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
emojiBtn=view.findViewById(R.id.btn_emoji);
|
emojiBtn=view.findViewById(R.id.btn_emoji);
|
||||||
spoilerBtn=view.findViewById(R.id.btn_spoiler);
|
spoilerBtn=view.findViewById(R.id.btn_spoiler);
|
||||||
visibilityBtn=view.findViewById(R.id.btn_visibility);
|
visibilityBtn=view.findViewById(R.id.btn_visibility);
|
||||||
|
contentTypeBtn=view.findViewById(R.id.btn_content_type);
|
||||||
scheduleDraftView=view.findViewById(R.id.schedule_draft_view);
|
scheduleDraftView=view.findViewById(R.id.schedule_draft_view);
|
||||||
scheduleDraftText=view.findViewById(R.id.schedule_draft_text);
|
scheduleDraftText=view.findViewById(R.id.schedule_draft_text);
|
||||||
scheduleDraftDismiss=view.findViewById(R.id.schedule_draft_dismiss);
|
scheduleDraftDismiss=view.findViewById(R.id.schedule_draft_dismiss);
|
||||||
@@ -364,6 +373,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
visibilityBtn.setOnClickListener(v->visibilityPopup.show());
|
visibilityBtn.setOnClickListener(v->visibilityPopup.show());
|
||||||
visibilityBtn.setOnTouchListener(visibilityPopup.getDragToOpenListener());
|
visibilityBtn.setOnTouchListener(visibilityPopup.getDragToOpenListener());
|
||||||
|
|
||||||
|
buildContentTypePopup(contentTypeBtn);
|
||||||
|
contentTypeBtn.setOnClickListener(v->contentTypePopup.show());
|
||||||
|
contentTypeBtn.setOnTouchListener(contentTypePopup.getDragToOpenListener());
|
||||||
|
|
||||||
scheduleDraftDismiss.setOnClickListener(v->updateScheduledAt(null));
|
scheduleDraftDismiss.setOnClickListener(v->updateScheduledAt(null));
|
||||||
scheduleTimeBtn.setOnClickListener(v->pickScheduledDateTime());
|
scheduleTimeBtn.setOnClickListener(v->pickScheduledDateTime());
|
||||||
|
|
||||||
@@ -466,8 +479,10 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(editingStatus!=null && editingStatus.visibility!=null) {
|
if (savedInstanceState != null) {
|
||||||
statusVisibility=editingStatus.visibility;
|
statusVisibility = (StatusPrivacy) savedInstanceState.getSerializable("visibility");
|
||||||
|
} else if (editingStatus != null && editingStatus.visibility != null) {
|
||||||
|
statusVisibility = editingStatus.visibility;
|
||||||
} else {
|
} else {
|
||||||
loadDefaultStatusVisibility(savedInstanceState);
|
loadDefaultStatusVisibility(savedInstanceState);
|
||||||
}
|
}
|
||||||
@@ -482,6 +497,20 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
}).setChecked(true);
|
}).setChecked(true);
|
||||||
visibilityPopup.getMenu().findItem(R.id.local_only).setChecked(localOnly);
|
visibilityPopup.getMenu().findItem(R.id.local_only).setChecked(localOnly);
|
||||||
|
|
||||||
|
|
||||||
|
if (savedInstanceState != null && savedInstanceState.containsKey("contentType")) {
|
||||||
|
contentType = (ContentType) savedInstanceState.getSerializable("contentType");
|
||||||
|
} else if (getArguments().containsKey("sourceContentType")) {
|
||||||
|
try {
|
||||||
|
String val = getArguments().getString("sourceContentType");
|
||||||
|
contentType = val == null ? null : ContentType.valueOf(val);
|
||||||
|
} catch (IllegalArgumentException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
int contentTypeId = ContentType.getContentTypeRes(contentType);
|
||||||
|
contentTypePopup.getMenu().findItem(contentTypeId).setChecked(true);
|
||||||
|
contentTypeBtn.setSelected(contentTypeId != R.id.content_type_null && contentTypeId != R.id.content_type_plain);
|
||||||
|
|
||||||
autocompleteViewController=new ComposeAutocompleteViewController(getActivity(), accountID);
|
autocompleteViewController=new ComposeAutocompleteViewController(getActivity(), accountID);
|
||||||
autocompleteViewController.setCompletionSelectedListener(this::onAutocompleteOptionSelected);
|
autocompleteViewController.setCompletionSelectedListener(this::onAutocompleteOptionSelected);
|
||||||
View autocompleteView=autocompleteViewController.getView();
|
View autocompleteView=autocompleteViewController.getView();
|
||||||
@@ -518,6 +547,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
outState.putParcelableArrayList("attachments", serializedAttachments);
|
outState.putParcelableArrayList("attachments", serializedAttachments);
|
||||||
}
|
}
|
||||||
outState.putSerializable("visibility", statusVisibility);
|
outState.putSerializable("visibility", statusVisibility);
|
||||||
|
outState.putSerializable("contentType", contentType);
|
||||||
if (scheduledAt != null) outState.putSerializable("scheduledAt", scheduledAt);
|
if (scheduledAt != null) outState.putSerializable("scheduledAt", scheduledAt);
|
||||||
if (scheduledStatus != null) outState.putParcelable("scheduledStatus", Parcels.wrap(scheduledStatus));
|
if (scheduledStatus != null) outState.putParcelable("scheduledStatus", Parcels.wrap(scheduledStatus));
|
||||||
}
|
}
|
||||||
@@ -907,6 +937,17 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getContentTypeName(String id) {
|
||||||
|
return switch (id) {
|
||||||
|
case "text/plain" -> R.string.sk_content_type_plain;
|
||||||
|
case "text/html" -> R.string.sk_content_type_html;
|
||||||
|
case "text/markdown" -> R.string.sk_content_type_markdown;
|
||||||
|
case "text/bbcode" -> R.string.sk_content_type_bbcode;
|
||||||
|
case "text/x.misskeymarkdown" -> R.string.sk_content_type_mfm;
|
||||||
|
default -> throw new IllegalArgumentException("Invalid content type");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void addBottomLanguage(Menu menu) {
|
private void addBottomLanguage(Menu menu) {
|
||||||
if (menu.findItem(allLanguages.size()) == null) {
|
if (menu.findItem(allLanguages.size()) == null) {
|
||||||
menu.add(0, allLanguages.size(), Menu.NONE, "bottom (\uD83E\uDD7A\uD83D\uDC49\uD83D\uDC48)");
|
menu.add(0, allLanguages.size(), Menu.NONE, "bottom (\uD83E\uDD7A\uD83D\uDC49\uD83D\uDC48)");
|
||||||
@@ -1053,6 +1094,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
req.visibility=localOnly && instance.pleroma != null ? StatusPrivacy.LOCAL : statusVisibility;
|
req.visibility=localOnly && instance.pleroma != null ? StatusPrivacy.LOCAL : statusVisibility;
|
||||||
req.sensitive=sensitive;
|
req.sensitive=sensitive;
|
||||||
req.language=language;
|
req.language=language;
|
||||||
|
req.contentType=contentType;
|
||||||
req.scheduledAt = scheduledAt;
|
req.scheduledAt = scheduledAt;
|
||||||
if(!attachments.isEmpty()){
|
if(!attachments.isEmpty()){
|
||||||
req.mediaIds=attachments.stream().map(a->a.serverAttachment.id).collect(Collectors.toList());
|
req.mediaIds=attachments.stream().map(a->a.serverAttachment.id).collect(Collectors.toList());
|
||||||
@@ -1547,7 +1589,8 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
if(att.isUploadingOrProcessing())
|
if(att.isUploadingOrProcessing())
|
||||||
att.cancelUpload();
|
att.cancelUpload();
|
||||||
attachments.remove(att);
|
attachments.remove(att);
|
||||||
uploadNextQueuedAttachment();
|
if(!areThereAnyUploadingAttachments())
|
||||||
|
uploadNextQueuedAttachment();
|
||||||
attachmentsView.removeView(att.view);
|
attachmentsView.removeView(att.view);
|
||||||
if(getMediaAttachmentsCount()==0)
|
if(getMediaAttachmentsCount()==0)
|
||||||
attachmentsView.setVisibility(View.GONE);
|
attachmentsView.setVisibility(View.GONE);
|
||||||
@@ -1894,14 +1937,36 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
private void buildContentTypePopup(View btn) {
|
||||||
|
contentTypePopup=new PopupMenu(getActivity(), btn);
|
||||||
|
contentTypePopup.inflate(R.menu.compose_content_type);
|
||||||
|
Menu m = contentTypePopup.getMenu();
|
||||||
|
ContentType.adaptMenuToInstance(m, instance);
|
||||||
|
if (contentType != null) m.findItem(R.id.content_type_null).setVisible(false);
|
||||||
|
|
||||||
|
contentTypePopup.setOnMenuItemClickListener(i->{
|
||||||
|
int id=i.getItemId();
|
||||||
|
if (id == R.id.content_type_null) contentType = null;
|
||||||
|
else if (id == R.id.content_type_plain) contentType = ContentType.PLAIN;
|
||||||
|
else if (id == R.id.content_type_html) contentType = ContentType.HTML;
|
||||||
|
else if (id == R.id.content_type_markdown) contentType = ContentType.MARKDOWN;
|
||||||
|
else if (id == R.id.content_type_bbcode) contentType = ContentType.BBCODE;
|
||||||
|
else if (id == R.id.content_type_misskey_markdown) contentType = ContentType.MISSKEY_MARKDOWN;
|
||||||
|
else return false;
|
||||||
|
btn.setSelected(id != R.id.content_type_null && id != R.id.content_type_plain);
|
||||||
|
i.setChecked(true);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!GlobalUserPreferences.accountsWithContentTypesEnabled.contains(accountID)) {
|
||||||
|
btn.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void loadDefaultStatusVisibility(Bundle savedInstanceState) {
|
private void loadDefaultStatusVisibility(Bundle savedInstanceState) {
|
||||||
if(replyTo != null) statusVisibility = replyTo.visibility;
|
if(replyTo != null) statusVisibility = replyTo.visibility;
|
||||||
|
|
||||||
// A saved privacy setting from a previous compose session wins over the reply visibility
|
|
||||||
if(savedInstanceState !=null){
|
|
||||||
statusVisibility = (StatusPrivacy) savedInstanceState.getSerializable("visibility");
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountSessionManager asm = AccountSessionManager.getInstance();
|
AccountSessionManager asm = AccountSessionManager.getInstance();
|
||||||
Preferences prefs = asm.getAccount(accountID).preferences;
|
Preferences prefs = asm.getAccount(accountID).preferences;
|
||||||
if (prefs != null) {
|
if (prefs != null) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.app.Activity;
|
|||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetFavoritedStatuses;
|
import org.joinmastodon.android.api.requests.statuses.GetFavoritedStatuses;
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.HeaderPaginationList;
|
import org.joinmastodon.android.model.HeaderPaginationList;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
|
|
||||||
@@ -35,4 +36,9 @@ public class FavoritedStatusListFragment extends StatusListFragment{
|
|||||||
})
|
})
|
||||||
.exec(accountID);
|
.exec(accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.ACCOUNT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public interface HasFab {
|
||||||
|
View getFab();
|
||||||
|
void showFab();
|
||||||
|
void hideFab();
|
||||||
|
}
|
||||||
@@ -39,7 +39,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment {
|
|||||||
private MenuItem followButton;
|
private MenuItem followButton;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Status> result){
|
public void onSuccess(List<Status> result){
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
result=result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.PUBLIC)).collect(Collectors.toList());
|
result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList());
|
||||||
onDataLoaded(result, !result.isEmpty());
|
onDataLoaded(result, !result.isEmpty());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -138,12 +138,12 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onFabLongClick(View v) {
|
public boolean onFabLongClick(View v) {
|
||||||
return UiUtils.pickAccountForCompose(getActivity(), accountID, '#'+hashtag+' ');
|
return UiUtils.pickAccountForCompose(getActivity(), accountID, '#'+hashtag+' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFabClick(View v){
|
public void onFabClick(View v){
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
args.putString("prefilledText", '#'+hashtag+' ');
|
args.putString("prefilledText", '#'+hashtag+' ');
|
||||||
@@ -154,4 +154,9 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment {
|
|||||||
protected void onSetFabBottomInset(int inset){
|
protected void onSetFabBottomInset(int inset){
|
||||||
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(24)+inset;
|
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(24)+inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.PUBLIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
|||||||
content.setOrientation(LinearLayout.VERTICAL);
|
content.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
|
||||||
FrameLayout fragmentContainer=new FrameLayout(getActivity());
|
FrameLayout fragmentContainer=new FrameLayout(getActivity());
|
||||||
fragmentContainer.setId(R.id.fragment_wrap);
|
fragmentContainer.setId(me.grishka.appkit.R.id.fragment_wrap);
|
||||||
content.addView(fragmentContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
|
content.addView(fragmentContainer, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0, 1f));
|
||||||
|
|
||||||
inflater.inflate(R.layout.tab_bar, content);
|
inflater.inflate(R.layout.tab_bar, content);
|
||||||
@@ -128,10 +128,10 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
|||||||
|
|
||||||
if(savedInstanceState==null){
|
if(savedInstanceState==null){
|
||||||
getChildFragmentManager().beginTransaction()
|
getChildFragmentManager().beginTransaction()
|
||||||
.add(R.id.fragment_wrap, homeTabFragment)
|
.add(me.grishka.appkit.R.id.fragment_wrap, homeTabFragment)
|
||||||
.add(R.id.fragment_wrap, searchFragment).hide(searchFragment)
|
.add(me.grishka.appkit.R.id.fragment_wrap, searchFragment).hide(searchFragment)
|
||||||
.add(R.id.fragment_wrap, notificationsFragment).hide(notificationsFragment)
|
.add(me.grishka.appkit.R.id.fragment_wrap, notificationsFragment).hide(notificationsFragment)
|
||||||
.add(R.id.fragment_wrap, profileFragment).hide(profileFragment)
|
.add(me.grishka.appkit.R.id.fragment_wrap, profileFragment).hide(profileFragment)
|
||||||
.commit();
|
.commit();
|
||||||
|
|
||||||
String defaultTab=getArguments().getString("tab");
|
String defaultTab=getArguments().getString("tab");
|
||||||
@@ -160,6 +160,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
|||||||
notificationsFragment=(NotificationsFragment) getChildFragmentManager().getFragment(savedInstanceState, "notificationsFragment");
|
notificationsFragment=(NotificationsFragment) getChildFragmentManager().getFragment(savedInstanceState, "notificationsFragment");
|
||||||
profileFragment=(ProfileFragment) getChildFragmentManager().getFragment(savedInstanceState, "profileFragment");
|
profileFragment=(ProfileFragment) getChildFragmentManager().getFragment(savedInstanceState, "profileFragment");
|
||||||
currentTab=savedInstanceState.getInt("selectedTab");
|
currentTab=savedInstanceState.getInt("selectedTab");
|
||||||
|
tabBar.selectTab(currentTab);
|
||||||
Fragment current=fragmentForTab(currentTab);
|
Fragment current=fragmentForTab(currentTab);
|
||||||
getChildFragmentManager().beginTransaction()
|
getChildFragmentManager().beginTransaction()
|
||||||
.hide(homeTabFragment)
|
.hide(homeTabFragment)
|
||||||
@@ -227,6 +228,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
|||||||
}
|
}
|
||||||
getChildFragmentManager().beginTransaction().hide(fragmentForTab(currentTab)).show(newFragment).commit();
|
getChildFragmentManager().beginTransaction().hide(fragmentForTab(currentTab)).show(newFragment).commit();
|
||||||
maybeTriggerLoading(newFragment);
|
maybeTriggerLoading(newFragment);
|
||||||
|
if (newFragment instanceof HasFab fabulous) fabulous.showFab();
|
||||||
currentTab=tab;
|
currentTab=tab;
|
||||||
((FragmentStackActivity)getActivity()).invalidateSystemBarColors(this);
|
((FragmentStackActivity)getActivity()).invalidateSystemBarColors(this);
|
||||||
}
|
}
|
||||||
@@ -291,7 +293,7 @@ public class HomeFragment extends AppKitFragment implements OnBackPressedListene
|
|||||||
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
Instance instance = AccountSessionManager.getInstance().getInstanceInfo(session.domain);
|
||||||
if (instance == null) return;
|
if (instance == null) return;
|
||||||
|
|
||||||
new GetNotifications(null, 1, EnumSet.allOf(Notification.Type.class), instance.pleroma != null)
|
new GetNotifications(null, 1, EnumSet.allOf(Notification.Type.class), instance != null && instance.pleroma != null)
|
||||||
.setCallback(new Callback<>() {
|
.setCallback(new Callback<>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Notification> notifications) {
|
public void onSuccess(List<Notification> notifications) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.view.ViewParent;
|
|||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.PopupMenu;
|
import android.widget.PopupMenu;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@@ -70,7 +71,7 @@ import me.grishka.appkit.fragments.OnBackPressedListener;
|
|||||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class HomeTabFragment extends MastodonToolbarFragment implements ScrollableToTop, OnBackPressedListener {
|
public class HomeTabFragment extends MastodonToolbarFragment implements ScrollableToTop, OnBackPressedListener, HasFab {
|
||||||
private static final int ANNOUNCEMENTS_RESULT = 654;
|
private static final int ANNOUNCEMENTS_RESULT = 654;
|
||||||
|
|
||||||
private String accountID;
|
private String accountID;
|
||||||
@@ -98,6 +99,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
|||||||
private PopupMenu overflowPopup;
|
private PopupMenu overflowPopup;
|
||||||
private View overflowActionView = null;
|
private View overflowActionView = null;
|
||||||
private boolean announcementsBadged, settingsBadged;
|
private boolean announcementsBadged, settingsBadged;
|
||||||
|
private ImageButton fab;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -122,6 +124,10 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
|||||||
@Override
|
@Override
|
||||||
public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
|
public View onCreateContentView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
|
||||||
FrameLayout view = new FrameLayout(getContext());
|
FrameLayout view = new FrameLayout(getContext());
|
||||||
|
inflater.inflate(R.layout.compose_fab, view);
|
||||||
|
fab = view.findViewById(R.id.fab);
|
||||||
|
fab.setOnClickListener(this::onFabClick);
|
||||||
|
fab.setOnLongClickListener(this::onFabLongClick);
|
||||||
pager = new ViewPager2(getContext());
|
pager = new ViewPager2(getContext());
|
||||||
toolbarFrame = (FrameLayout) LayoutInflater.from(getContext()).inflate(R.layout.home_toolbar, getToolbar(), false);
|
toolbarFrame = (FrameLayout) LayoutInflater.from(getContext()).inflate(R.layout.home_toolbar, getToolbar(), false);
|
||||||
|
|
||||||
@@ -129,6 +135,7 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
|||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
args.putBoolean("__is_tab", true);
|
args.putBoolean("__is_tab", true);
|
||||||
|
args.putBoolean("__disable_fab", true);
|
||||||
args.putBoolean("onlyPosts", true);
|
args.putBoolean("onlyPosts", true);
|
||||||
|
|
||||||
for (int i = 0; i < timelineDefinitions.size(); i++) {
|
for (int i = 0; i < timelineDefinitions.size(); i++) {
|
||||||
@@ -280,6 +287,20 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
|||||||
}).exec(accountID);
|
}).exec(accountID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onFabClick(View v){
|
||||||
|
if (fragments[pager.getCurrentItem()] instanceof BaseStatusListFragment<?> l) {
|
||||||
|
l.onFabClick(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean onFabLongClick(View v) {
|
||||||
|
if (fragments[pager.getCurrentItem()] instanceof BaseStatusListFragment<?> l) {
|
||||||
|
return l.onFabLongClick(v);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addListsToOverflowMenu() {
|
private void addListsToOverflowMenu() {
|
||||||
Context ctx = getContext();
|
Context ctx = getContext();
|
||||||
listsMenu.clear();
|
listsMenu.clear();
|
||||||
@@ -427,9 +448,20 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
|||||||
updateSwitcherIcon(i);
|
updateSwitcherIcon(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showFab() {
|
||||||
|
if (fragments[pager.getCurrentItem()] instanceof BaseStatusListFragment<?> l) l.showFab();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideFab() {
|
||||||
|
if (fragments[pager.getCurrentItem()] instanceof BaseStatusListFragment<?> l) l.hideFab();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateSwitcherIcon(int i) {
|
private void updateSwitcherIcon(int i) {
|
||||||
timelineIcon.setImageResource(timelines[i].getIcon().iconRes);
|
timelineIcon.setImageResource(timelines[i].getIcon().iconRes);
|
||||||
timelineTitle.setText(timelines[i].getTitle(getContext()));
|
timelineTitle.setText(timelines[i].getTitle(getContext()));
|
||||||
|
showFab();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -657,6 +689,10 @@ public class HomeTabFragment extends MastodonToolbarFragment implements Scrollab
|
|||||||
return hashtagsItems.values();
|
return hashtagsItems.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ImageButton getFab() {
|
||||||
|
return fab;
|
||||||
|
}
|
||||||
|
|
||||||
private class HomePagerAdapter extends RecyclerView.Adapter<SimpleViewHolder> {
|
private class HomePagerAdapter extends RecyclerView.Adapter<SimpleViewHolder> {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.E;
|
|
||||||
import org.joinmastodon.android.R;
|
|
||||||
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
|
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
|
||||||
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
|
import org.joinmastodon.android.api.requests.timelines.GetHomeTimeline;
|
||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
@@ -38,7 +36,7 @@ public class HomeTimelineFragment extends StatusListFragment {
|
|||||||
private String lastSavedMarkerID;
|
private String lastSavedMarkerID;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +148,7 @@ public class HomeTimelineFragment extends StatusListFragment {
|
|||||||
result.get(result.size()-1).hasGapAfter=true;
|
result.get(result.size()-1).hasGapAfter=true;
|
||||||
toAdd=result;
|
toAdd=result;
|
||||||
}
|
}
|
||||||
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, Filter.FilterContext.HOME);
|
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, getFilterContext());
|
||||||
toAdd=toAdd.stream().filter(filterPredicate).collect(Collectors.toList());
|
toAdd=toAdd.stream().filter(filterPredicate).collect(Collectors.toList());
|
||||||
if(!toAdd.isEmpty()){
|
if(!toAdd.isEmpty()){
|
||||||
prependItems(toAdd, true);
|
prependItems(toAdd, true);
|
||||||
@@ -229,7 +227,7 @@ public class HomeTimelineFragment extends StatusListFragment {
|
|||||||
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
|
List<StatusDisplayItem> targetList=displayItems.subList(gapPos, gapPos+1);
|
||||||
targetList.clear();
|
targetList.clear();
|
||||||
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
|
List<Status> insertedPosts=data.subList(gapPostIndex+1, gapPostIndex+1);
|
||||||
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, Filter.FilterContext.HOME);
|
StatusFilterPredicate filterPredicate=new StatusFilterPredicate(accountID, getFilterContext());
|
||||||
for(Status s:result){
|
for(Status s:result){
|
||||||
if(idsBelowGap.contains(s.id))
|
if(idsBelowGap.contains(s.id))
|
||||||
break;
|
break;
|
||||||
@@ -282,4 +280,9 @@ public class HomeTimelineFragment extends StatusListFragment {
|
|||||||
protected boolean shouldRemoveAccountPostsWhenUnfollowing(){
|
protected boolean shouldRemoveAccountPostsWhenUnfollowing(){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.HOME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment {
|
|||||||
private ListTimeline.RepliesPolicy repliesPolicy;
|
private ListTimeline.RepliesPolicy repliesPolicy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Status> result) {
|
public void onSuccess(List<Status> result) {
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
result=result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.HOME)).collect(Collectors.toList());
|
result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList());
|
||||||
onDataLoaded(result, !result.isEmpty());
|
onDataLoaded(result, !result.isEmpty());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -152,7 +152,7 @@ public class ListTimelineFragment extends PinnableStatusListFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFabClick(View v){
|
public void onFabClick(View v){
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
Nav.go(getActivity(), ComposeFragment.class, args);
|
Nav.go(getActivity(), ComposeFragment.class, args);
|
||||||
@@ -162,4 +162,10 @@ public class ListTimelineFragment extends PinnableStatusListFragment {
|
|||||||
protected void onSetFabBottomInset(int inset) {
|
protected void onSetFabBottomInset(int inset) {
|
||||||
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(24)+inset;
|
((ViewGroup.MarginLayoutParams) fab.getLayoutParams()).bottomMargin=V.dp(24)+inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.HOME;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,14 +16,15 @@ import org.joinmastodon.android.events.PollUpdatedEvent;
|
|||||||
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.CacheablePaginatedResponse;
|
import org.joinmastodon.android.model.CacheablePaginatedResponse;
|
||||||
|
import org.joinmastodon.android.model.Emoji;
|
||||||
import org.joinmastodon.android.model.Filter;
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.Notification;
|
import org.joinmastodon.android.model.Notification;
|
||||||
import org.joinmastodon.android.model.PaginatedResponse;
|
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.AccountCardStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.TextStatusDisplayItem;
|
||||||
|
import org.joinmastodon.android.ui.text.HtmlParser;
|
||||||
import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper;
|
import org.joinmastodon.android.ui.utils.DiscoverInfoBannerHelper;
|
||||||
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
|
import org.joinmastodon.android.ui.utils.InsetStatusItemDecoration;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
@@ -48,8 +49,8 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
|||||||
private final DiscoverInfoBannerHelper bannerHelper = new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.POST_NOTIFICATIONS);
|
private final DiscoverInfoBannerHelper bannerHelper = new DiscoverInfoBannerHelper(DiscoverInfoBannerHelper.BannerType.POST_NOTIFICATIONS);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -83,6 +84,13 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
|||||||
protected List<StatusDisplayItem> buildDisplayItems(Notification n){
|
protected List<StatusDisplayItem> buildDisplayItems(Notification n){
|
||||||
Account reportTarget = n.report == null ? null : n.report.targetAccount == null ? null :
|
Account reportTarget = n.report == null ? null : n.report.targetAccount == null ? null :
|
||||||
n.report.targetAccount;
|
n.report.targetAccount;
|
||||||
|
Emoji emoji = new Emoji();
|
||||||
|
if(n.emojiUrl!=null){
|
||||||
|
emoji.shortcode=n.emoji.substring(1,n.emoji.length()-1);
|
||||||
|
emoji.url=n.emojiUrl;
|
||||||
|
emoji.staticUrl=n.emojiUrl;
|
||||||
|
emoji.visibleInPicker=false;
|
||||||
|
}
|
||||||
String extraText=switch(n.type){
|
String extraText=switch(n.type){
|
||||||
case FOLLOW -> getString(R.string.user_followed_you);
|
case FOLLOW -> getString(R.string.user_followed_you);
|
||||||
case FOLLOW_REQUEST -> getString(R.string.user_sent_follow_request);
|
case FOLLOW_REQUEST -> getString(R.string.user_sent_follow_request);
|
||||||
@@ -93,8 +101,10 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
|||||||
case UPDATE -> getString(R.string.sk_post_edited);
|
case UPDATE -> getString(R.string.sk_post_edited);
|
||||||
case SIGN_UP -> getString(R.string.sk_signed_up);
|
case SIGN_UP -> getString(R.string.sk_signed_up);
|
||||||
case REPORT -> getString(R.string.sk_reported);
|
case REPORT -> getString(R.string.sk_reported);
|
||||||
|
case REACTION, PLEROMA_EMOJI_REACTION ->
|
||||||
|
n.emoji != null ? getString(R.string.sk_reacted_with, n.emoji) : getString(R.string.sk_reacted);
|
||||||
};
|
};
|
||||||
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, n.status, extraText, n, null) : null;
|
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, n.status, n.emojiUrl!=null ? HtmlParser.parseCustomEmoji(extraText, Collections.singletonList(emoji)) : extraText, n, null) : null;
|
||||||
if(n.status!=null){
|
if(n.status!=null){
|
||||||
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null, n, false, Filter.FilterContext.NOTIFICATIONS);
|
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null, n, false, Filter.FilterContext.NOTIFICATIONS);
|
||||||
if(titleItem!=null)
|
if(titleItem!=null)
|
||||||
@@ -144,8 +154,9 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
|||||||
if(offset==0 && !result.items.isEmpty() && !result.isFromCache()){
|
if(offset==0 && !result.items.isEmpty() && !result.isFromCache()){
|
||||||
E.post(new AllNotificationsSeenEvent());
|
E.post(new AllNotificationsSeenEvent());
|
||||||
new SaveMarkers(null, result.items.get(0).id).exec(accountID);
|
new SaveMarkers(null, result.items.get(0).id).exec(accountID);
|
||||||
AccountSessionManager.getInstance().getAccount(accountID).markers
|
if (AccountSessionManager.getInstance().getAccount(accountID).markers != null)
|
||||||
.notifications.lastReadId = result.items.get(0).id;
|
AccountSessionManager.getInstance().getAccount(accountID).markers
|
||||||
|
.notifications.lastReadId = result.items.get(0).id;
|
||||||
AccountSessionManager.getInstance().writeAccountsFile();
|
AccountSessionManager.getInstance().writeAccountsFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +207,6 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
|
|||||||
public void onViewCreated(View view, Bundle savedInstanceState){
|
public void onViewCreated(View view, Bundle savedInstanceState){
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
list.addItemDecoration(new InsetStatusItemDecoration(this));
|
list.addItemDecoration(new InsetStatusItemDecoration(this));
|
||||||
if (getParentFragment() instanceof NotificationsFragment) fab.setVisibility(View.GONE);
|
|
||||||
if (onlyPosts) bannerHelper.maybeAddBanner(contentWrap);
|
if (onlyPosts) bannerHelper.maybeAddBanner(contentWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -337,7 +337,7 @@ public class ProfileAboutFragment extends Fragment implements WindowInsetsAwareF
|
|||||||
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState){
|
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState){
|
||||||
super.onSelectedChanged(viewHolder, actionState);
|
super.onSelectedChanged(viewHolder, actionState);
|
||||||
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
|
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
|
||||||
viewHolder.itemView.setTag(R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw()
|
viewHolder.itemView.setTag(me.grishka.appkit.R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw()
|
||||||
viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||||
draggedViewHolder=viewHolder;
|
draggedViewHolder=viewHolder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,13 +19,11 @@ import android.os.Bundle;
|
|||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.style.ImageSpan;
|
import android.text.style.ImageSpan;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.MotionEvent;
|
|
||||||
import android.view.SubMenu;
|
import android.view.SubMenu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -112,7 +110,7 @@ import me.grishka.appkit.utils.CubicBezierInterpolator;
|
|||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
import me.grishka.appkit.views.UsableRecyclerView;
|
import me.grishka.appkit.views.UsableRecyclerView;
|
||||||
|
|
||||||
public class ProfileFragment extends LoaderFragment implements OnBackPressedListener, ScrollableToTop{
|
public class ProfileFragment extends LoaderFragment implements OnBackPressedListener, ScrollableToTop, HasFab{
|
||||||
private static final int AVATAR_RESULT=722;
|
private static final int AVATAR_RESULT=722;
|
||||||
private static final int COVER_RESULT=343;
|
private static final int COVER_RESULT=343;
|
||||||
|
|
||||||
@@ -152,7 +150,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
private WindowInsets childInsets;
|
private WindowInsets childInsets;
|
||||||
private PhotoViewer currentPhotoViewer;
|
private PhotoViewer currentPhotoViewer;
|
||||||
private boolean editModeLoading;
|
private boolean editModeLoading;
|
||||||
protected int scrollDiff = 0;
|
|
||||||
|
|
||||||
private static final int MAX_FIELDS=4;
|
private static final int MAX_FIELDS=4;
|
||||||
|
|
||||||
@@ -761,6 +758,16 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
return fab;
|
return fab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showFab() {
|
||||||
|
if (getFragmentForPage(pager.getCurrentItem()) instanceof HasFab fabulous) fabulous.showFab();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideFab() {
|
||||||
|
if (getFragmentForPage(pager.getCurrentItem()) instanceof HasFab fabulous) fabulous.hideFab();
|
||||||
|
}
|
||||||
|
|
||||||
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
|
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){
|
||||||
int topBarsH=getToolbar().getHeight()+statusBarHeight;
|
int topBarsH=getToolbar().getHeight()+statusBarHeight;
|
||||||
if(scrollY>avatarBorder.getTop()-topBarsH){
|
if(scrollY>avatarBorder.getTop()-topBarsH){
|
||||||
@@ -791,35 +798,6 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
if(currentPhotoViewer!=null){
|
if(currentPhotoViewer!=null){
|
||||||
currentPhotoViewer.offsetView(0, oldScrollY-scrollY);
|
currentPhotoViewer.offsetView(0, oldScrollY-scrollY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GlobalUserPreferences.autoHideFab) {
|
|
||||||
int dy = scrollY - oldScrollY;
|
|
||||||
if (dy > 0 && fab.getVisibility() == View.VISIBLE) {
|
|
||||||
TranslateAnimation animate = new TranslateAnimation(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
fab.getHeight() * 2);
|
|
||||||
animate.setDuration(300);
|
|
||||||
fab.startAnimation(animate);
|
|
||||||
fab.setVisibility(View.INVISIBLE);
|
|
||||||
scrollDiff = 0;
|
|
||||||
} else if (dy < 0 && fab.getVisibility() != View.VISIBLE) {
|
|
||||||
if (v.getScrollY() == 0 || scrollDiff > 400) {
|
|
||||||
fab.setVisibility(View.VISIBLE);
|
|
||||||
TranslateAnimation animate = new TranslateAnimation(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
fab.getHeight() * 2,
|
|
||||||
0);
|
|
||||||
animate.setDuration(300);
|
|
||||||
fab.startAnimation(animate);
|
|
||||||
scrollDiff = 0;
|
|
||||||
} else {
|
|
||||||
scrollDiff += Math.abs(dy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Fragment getFragmentForPage(int page){
|
private Fragment getFragmentForPage(int page){
|
||||||
@@ -1375,7 +1353,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
|
|||||||
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState){
|
public void onSelectedChanged(@Nullable RecyclerView.ViewHolder viewHolder, int actionState){
|
||||||
super.onSelectedChanged(viewHolder, actionState);
|
super.onSelectedChanged(viewHolder, actionState);
|
||||||
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
|
if(actionState==ItemTouchHelper.ACTION_STATE_DRAG){
|
||||||
viewHolder.itemView.setTag(R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw()
|
viewHolder.itemView.setTag(me.grishka.appkit.R.id.item_touch_helper_previous_elevation, viewHolder.itemView.getElevation()); // prevents the default behavior of changing elevation in onDraw()
|
||||||
viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
viewHolder.itemView.animate().translationZ(V.dp(1)).setDuration(200).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
|
||||||
draggedViewHolder=viewHolder;
|
draggedViewHolder=viewHolder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
|
|||||||
private static final int SCHEDULED_STATUS_LIST_OPENED = 161;
|
private static final int SCHEDULED_STATUS_LIST_OPENED = 161;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFabClick(View v) {
|
public void onFabClick(View v) {
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
args.putSerializable("scheduledAt", CreateStatus.getDraftInstant());
|
args.putSerializable("scheduledAt", CreateStatus.getDraftInstant());
|
||||||
@@ -64,7 +64,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onFabLongClick(View v) {
|
public boolean onFabLongClick(View v) {
|
||||||
Bundle args=new Bundle();
|
Bundle args=new Bundle();
|
||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
args.putSerializable("scheduledAt", CreateStatus.getDraftInstant());
|
args.putSerializable("scheduledAt", CreateStatus.getDraftInstant());
|
||||||
@@ -79,7 +79,7 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<StatusDisplayItem> buildDisplayItems(ScheduledStatus s) {
|
protected List<StatusDisplayItem> buildDisplayItems(ScheduledStatus s) {
|
||||||
return StatusDisplayItem.buildItems(this, s.toStatus(), accountID, s, knownAccounts, false, false, null, true);
|
return StatusDisplayItem.buildItems(this, s.toStatus(), accountID, s, knownAccounts, false, false, null, true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -96,6 +96,8 @@ public class ScheduledStatusListFragment extends BaseStatusListFragment<Schedule
|
|||||||
args.putString("sourceText", status.text);
|
args.putString("sourceText", status.text);
|
||||||
args.putString("sourceSpoiler", status.spoilerText);
|
args.putString("sourceSpoiler", status.spoilerText);
|
||||||
args.putBoolean("redraftStatus", true);
|
args.putBoolean("redraftStatus", true);
|
||||||
|
args.putString("sourceContentType", scheduledStatus.params.contentType != null ?
|
||||||
|
scheduledStatus.params.contentType.name() : null);
|
||||||
setResult(true, null);
|
setResult(true, null);
|
||||||
|
|
||||||
// closing this scheduled status list if another status list is opened from compose fragment
|
// closing this scheduled status list if another status list is opened from compose fragment
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import android.util.LruCache;
|
|||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -48,6 +49,7 @@ import org.joinmastodon.android.api.session.AccountSession;
|
|||||||
import org.joinmastodon.android.api.session.AccountSessionManager;
|
import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
||||||
import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment;
|
import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.Instance;
|
import org.joinmastodon.android.model.Instance;
|
||||||
import org.joinmastodon.android.fragments.onboarding.AccountActivationFragment;
|
import org.joinmastodon.android.fragments.onboarding.AccountActivationFragment;
|
||||||
import org.joinmastodon.android.model.PushNotification;
|
import org.joinmastodon.android.model.PushNotification;
|
||||||
@@ -64,6 +66,7 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
import androidx.annotation.DrawableRes;
|
import androidx.annotation.DrawableRes;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -80,7 +83,8 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
private ArrayList<Item> items=new ArrayList<>();
|
private ArrayList<Item> items=new ArrayList<>();
|
||||||
private ThemeItem themeItem;
|
private ThemeItem themeItem;
|
||||||
private NotificationPolicyItem notificationPolicyItem;
|
private NotificationPolicyItem notificationPolicyItem;
|
||||||
private SwitchItem showNewPostsButtonItem, glitchModeItem, compactReblogReplyLineItem;
|
private SwitchItem showNewPostsItem, glitchModeItem, compactReblogReplyLineItem;
|
||||||
|
private ButtonItem defaultContentTypeButtonItem;
|
||||||
private String accountID;
|
private String accountID;
|
||||||
private boolean needUpdateNotificationSettings;
|
private boolean needUpdateNotificationSettings;
|
||||||
private boolean needAppRestart;
|
private boolean needAppRestart;
|
||||||
@@ -89,7 +93,9 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
private ImageView themeTransitionWindowView;
|
private ImageView themeTransitionWindowView;
|
||||||
private TextItem checkForUpdateItem, clearImageCacheItem;
|
private TextItem checkForUpdateItem, clearImageCacheItem;
|
||||||
private ImageCache imageCache;
|
private ImageCache imageCache;
|
||||||
|
private Menu contentTypeMenu;
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -207,6 +213,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
GlobalUserPreferences.prefixRepliesWithRe=i.checked;
|
GlobalUserPreferences.prefixRepliesWithRe=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
|
items.add(new SwitchItem(R.string.sk_settings_confirm_before_reblog, R.drawable.ic_fluent_checkmark_circle_24_regular, GlobalUserPreferences.confirmBeforeReblog, i->{
|
||||||
|
GlobalUserPreferences.confirmBeforeReblog=i.checked;
|
||||||
|
GlobalUserPreferences.save();
|
||||||
|
}));
|
||||||
|
|
||||||
items.add(new HeaderItem(R.string.sk_timelines));
|
items.add(new HeaderItem(R.string.sk_timelines));
|
||||||
items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
|
||||||
@@ -235,15 +245,15 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
}));
|
}));
|
||||||
items.add(new SwitchItem(R.string.sk_settings_load_new_posts, R.drawable.ic_fluent_arrow_sync_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
items.add(new SwitchItem(R.string.sk_settings_load_new_posts, R.drawable.ic_fluent_arrow_sync_24_regular, GlobalUserPreferences.loadNewPosts, i->{
|
||||||
GlobalUserPreferences.loadNewPosts=i.checked;
|
GlobalUserPreferences.loadNewPosts=i.checked;
|
||||||
showNewPostsButtonItem.enabled = i.checked;
|
showNewPostsItem.enabled = i.checked;
|
||||||
if (!i.checked) {
|
if (!i.checked) {
|
||||||
GlobalUserPreferences.showNewPostsButton = false;
|
GlobalUserPreferences.showNewPostsButton = false;
|
||||||
showNewPostsButtonItem.checked = false;
|
showNewPostsItem.checked = false;
|
||||||
}
|
}
|
||||||
if (list.findViewHolderForAdapterPosition(items.indexOf(showNewPostsButtonItem)) instanceof SwitchViewHolder svh) svh.rebind();
|
if (list.findViewHolderForAdapterPosition(items.indexOf(showNewPostsItem)) instanceof SwitchViewHolder svh) svh.rebind();
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
items.add(showNewPostsButtonItem = new SwitchItem(R.string.sk_settings_see_new_posts_button, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.showNewPostsButton, i->{
|
items.add(showNewPostsItem = new SwitchItem(R.string.sk_settings_see_new_posts_button, R.drawable.ic_fluent_arrow_up_24_regular, GlobalUserPreferences.showNewPostsButton, i->{
|
||||||
GlobalUserPreferences.showNewPostsButton=i.checked;
|
GlobalUserPreferences.showNewPostsButton=i.checked;
|
||||||
GlobalUserPreferences.save();
|
GlobalUserPreferences.save();
|
||||||
}));
|
}));
|
||||||
@@ -326,6 +336,36 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
if (!TextUtils.isEmpty(instance.version)) items.add(new SmallTextItem(getString(R.string.sk_settings_server_version, instance.version)));
|
if (!TextUtils.isEmpty(instance.version)) items.add(new SmallTextItem(getString(R.string.sk_settings_server_version, instance.version)));
|
||||||
|
|
||||||
items.add(new HeaderItem(R.string.sk_instance_features));
|
items.add(new HeaderItem(R.string.sk_instance_features));
|
||||||
|
items.add(new SwitchItem(R.string.sk_settings_content_types, 0, GlobalUserPreferences.accountsWithContentTypesEnabled.contains(accountID), (i)->{
|
||||||
|
if (i.checked) {
|
||||||
|
GlobalUserPreferences.accountsWithContentTypesEnabled.add(accountID);
|
||||||
|
if (GlobalUserPreferences.accountsDefaultContentTypes.get(accountID) == null) {
|
||||||
|
GlobalUserPreferences.accountsDefaultContentTypes.put(accountID, ContentType.PLAIN);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GlobalUserPreferences.accountsWithContentTypesEnabled.remove(accountID);
|
||||||
|
GlobalUserPreferences.accountsDefaultContentTypes.remove(accountID);
|
||||||
|
}
|
||||||
|
if (list.findViewHolderForAdapterPosition(items.indexOf(defaultContentTypeButtonItem))
|
||||||
|
instanceof ButtonViewHolder bvh) bvh.rebind();
|
||||||
|
GlobalUserPreferences.save();
|
||||||
|
}));
|
||||||
|
items.add(new SmallTextItem(getString(R.string.sk_settings_content_types_explanation)));
|
||||||
|
items.add(defaultContentTypeButtonItem = new ButtonItem(R.string.sk_settings_default_content_type, 0, b->{
|
||||||
|
PopupMenu popupMenu=new PopupMenu(getActivity(), b, Gravity.CENTER_HORIZONTAL);
|
||||||
|
popupMenu.inflate(R.menu.compose_content_type);
|
||||||
|
popupMenu.setOnMenuItemClickListener(item -> this.onContentTypeChanged(item, b));
|
||||||
|
b.setOnTouchListener(popupMenu.getDragToOpenListener());
|
||||||
|
b.setOnClickListener(v->popupMenu.show());
|
||||||
|
ContentType contentType = GlobalUserPreferences.accountsDefaultContentTypes.get(accountID);
|
||||||
|
b.setText(getContentTypeString(contentType));
|
||||||
|
contentTypeMenu = popupMenu.getMenu();
|
||||||
|
contentTypeMenu.findItem(ContentType.getContentTypeRes(contentType)).setChecked(true);
|
||||||
|
ContentType.adaptMenuToInstance(contentTypeMenu, instance);
|
||||||
|
contentTypeMenu.findItem(R.id.content_type_null).setVisible(
|
||||||
|
!GlobalUserPreferences.accountsWithContentTypesEnabled.contains(accountID));
|
||||||
|
}));
|
||||||
|
items.add(new SmallTextItem(getString(R.string.sk_settings_default_content_type_explanation)));
|
||||||
items.add(new SwitchItem(R.string.sk_settings_support_local_only, 0, GlobalUserPreferences.accountsWithLocalOnlySupport.contains(accountID), i->{
|
items.add(new SwitchItem(R.string.sk_settings_support_local_only, 0, GlobalUserPreferences.accountsWithLocalOnlySupport.contains(accountID), i->{
|
||||||
glitchModeItem.enabled = i.checked;
|
glitchModeItem.enabled = i.checked;
|
||||||
if (i.checked) {
|
if (i.checked) {
|
||||||
@@ -496,6 +536,34 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private @StringRes int getContentTypeString(@Nullable ContentType contentType) {
|
||||||
|
if (contentType == null) return R.string.sk_content_type_unspecified;
|
||||||
|
return switch (contentType) {
|
||||||
|
case PLAIN -> R.string.sk_content_type_plain;
|
||||||
|
case HTML -> R.string.sk_content_type_html;
|
||||||
|
case MARKDOWN -> R.string.sk_content_type_markdown;
|
||||||
|
case BBCODE -> R.string.sk_content_type_bbcode;
|
||||||
|
case MISSKEY_MARKDOWN -> R.string.sk_content_type_mfm;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean onContentTypeChanged(MenuItem item, Button btn){
|
||||||
|
int id = item.getItemId();
|
||||||
|
ContentType contentType = switch (id) {
|
||||||
|
case R.id.content_type_plain -> ContentType.PLAIN;
|
||||||
|
case R.id.content_type_html -> ContentType.HTML;
|
||||||
|
case R.id.content_type_markdown -> ContentType.MARKDOWN;
|
||||||
|
case R.id.content_type_bbcode -> ContentType.BBCODE;
|
||||||
|
case R.id.content_type_misskey_markdown -> ContentType.MISSKEY_MARKDOWN;
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
GlobalUserPreferences.accountsDefaultContentTypes.put(accountID, contentType);
|
||||||
|
GlobalUserPreferences.save();
|
||||||
|
btn.setText(getContentTypeString(contentType));
|
||||||
|
item.setChecked(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean onReplyVisibilityChanged(MenuItem item, Button btn){
|
private boolean onReplyVisibilityChanged(MenuItem item, Button btn){
|
||||||
String pref = null;
|
String pref = null;
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
@@ -1003,7 +1071,11 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
|||||||
@Override
|
@Override
|
||||||
public void onBind(ButtonItem item){
|
public void onBind(ButtonItem item){
|
||||||
text.setText(item.text);
|
text.setText(item.text);
|
||||||
icon.setImageResource(item.icon);
|
if (item.icon == 0) {
|
||||||
|
icon.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
icon.setImageResource(item.icon);
|
||||||
|
}
|
||||||
item.buttonConsumer.accept(button);
|
item.buttonConsumer.accept(button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,47 @@
|
|||||||
package org.joinmastodon.android.fragments;
|
package org.joinmastodon.android.fragments;
|
||||||
|
|
||||||
import android.graphics.Canvas;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.SpannableString;
|
|
||||||
import android.text.style.ReplacementSpan;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.WindowInsets;
|
import android.view.WindowInsets;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
|
import org.joinmastodon.android.MastodonApp;
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
|
import org.joinmastodon.android.api.requests.instance.GetInstance;
|
||||||
import org.joinmastodon.android.fragments.onboarding.InstanceCatalogSignupFragment;
|
import org.joinmastodon.android.fragments.onboarding.InstanceCatalogSignupFragment;
|
||||||
import org.joinmastodon.android.fragments.onboarding.InstanceChooserLoginFragment;
|
import org.joinmastodon.android.fragments.onboarding.InstanceChooserLoginFragment;
|
||||||
|
import org.joinmastodon.android.fragments.onboarding.InstanceRulesFragment;
|
||||||
|
import org.joinmastodon.android.model.Instance;
|
||||||
|
import org.joinmastodon.android.ui.InterpolatingMotionEffect;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.ui.views.SizeListenerFrameLayout;
|
import org.joinmastodon.android.ui.views.SizeListenerFrameLayout;
|
||||||
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
|
import me.grishka.appkit.api.Callback;
|
||||||
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
import me.grishka.appkit.fragments.AppKitFragment;
|
import me.grishka.appkit.fragments.AppKitFragment;
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
import me.grishka.appkit.views.BottomSheet;
|
||||||
|
|
||||||
public class SplashFragment extends AppKitFragment{
|
public class SplashFragment extends AppKitFragment{
|
||||||
|
|
||||||
|
private static final String DEFAULT_SERVER="mastodon.social";
|
||||||
|
|
||||||
private SizeListenerFrameLayout contentView;
|
private SizeListenerFrameLayout contentView;
|
||||||
private View artContainer, blueFill, greenFill;
|
private View artContainer, blueFill, greenFill;
|
||||||
private ViewPager2 pager;
|
private InterpolatingMotionEffect motionEffect;
|
||||||
private ViewGroup pagerDots;
|
|
||||||
private View artClouds, artPlaneElephant, artRightHill, artLeftHill, artCenterHill;
|
private View artClouds, artPlaneElephant, artRightHill, artLeftHill, artCenterHill;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
motionEffect=new InterpolatingMotionEffect(MastodonApp.context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -46,44 +50,26 @@ public class SplashFragment extends AppKitFragment{
|
|||||||
contentView=(SizeListenerFrameLayout) inflater.inflate(R.layout.fragment_splash, container, false);
|
contentView=(SizeListenerFrameLayout) inflater.inflate(R.layout.fragment_splash, container, false);
|
||||||
contentView.findViewById(R.id.btn_get_started).setOnClickListener(this::onButtonClick);
|
contentView.findViewById(R.id.btn_get_started).setOnClickListener(this::onButtonClick);
|
||||||
contentView.findViewById(R.id.btn_log_in).setOnClickListener(this::onButtonClick);
|
contentView.findViewById(R.id.btn_log_in).setOnClickListener(this::onButtonClick);
|
||||||
|
Button joinDefault=contentView.findViewById(R.id.btn_join_default_server);
|
||||||
|
joinDefault.setText(getString(R.string.join_default_server, DEFAULT_SERVER));
|
||||||
|
joinDefault.setOnClickListener(this::onJoinDefaultServerClick);
|
||||||
|
contentView.findViewById(R.id.btn_learn_more).setOnClickListener(this::onLearnMoreClick);
|
||||||
|
|
||||||
artClouds=contentView.findViewById(R.id.art_clouds);
|
artClouds=contentView.findViewById(R.id.art_clouds);
|
||||||
artPlaneElephant=contentView.findViewById(R.id.art_plane_elephant);
|
artPlaneElephant=contentView.findViewById(R.id.art_plane_elephant);
|
||||||
artRightHill=contentView.findViewById(R.id.art_right_hill);
|
artRightHill=contentView.findViewById(R.id.art_right_hill);
|
||||||
artLeftHill=contentView.findViewById(R.id.art_left_hill);
|
artLeftHill=contentView.findViewById(R.id.art_left_hill);
|
||||||
artCenterHill=contentView.findViewById(R.id.art_center_hill);
|
artCenterHill=contentView.findViewById(R.id.art_center_hill);
|
||||||
pager=contentView.findViewById(R.id.pager);
|
|
||||||
pagerDots=contentView.findViewById(R.id.pager_dots);
|
|
||||||
pager.setAdapter(new PagerAdapter());
|
|
||||||
pager.setOffscreenPageLimit(3);
|
|
||||||
pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback(){
|
|
||||||
@Override
|
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels){
|
|
||||||
for(int i=0;i<pagerDots.getChildCount();i++){
|
|
||||||
float alpha;
|
|
||||||
if(i==position){
|
|
||||||
alpha=0.3f+0.7f*(1f-positionOffset);
|
|
||||||
}else if(i==position+1){
|
|
||||||
alpha=0.3f+0.7f*positionOffset;
|
|
||||||
}else{
|
|
||||||
alpha=0.3f;
|
|
||||||
}
|
|
||||||
pagerDots.getChildAt(i).setAlpha(alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
float parallaxProgress=(position+positionOffset)/2f;
|
|
||||||
artClouds.setTranslationX(V.dp(-27)*(position>=1 ? 1f : positionOffset));
|
|
||||||
artPlaneElephant.setTranslationX(V.dp(101.55f)*parallaxProgress);
|
|
||||||
artLeftHill.setTranslationX(V.dp(-88)*parallaxProgress);
|
|
||||||
artLeftHill.setTranslationY(V.dp(24)*parallaxProgress);
|
|
||||||
artRightHill.setTranslationX(V.dp(-88)*parallaxProgress);
|
|
||||||
artRightHill.setTranslationY(V.dp(-24)*parallaxProgress);
|
|
||||||
artCenterHill.setTranslationX(V.dp(-40)*parallaxProgress);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
artContainer=contentView.findViewById(R.id.art_container);
|
artContainer=contentView.findViewById(R.id.art_container);
|
||||||
blueFill=contentView.findViewById(R.id.blue_fill);
|
blueFill=contentView.findViewById(R.id.blue_fill);
|
||||||
greenFill=contentView.findViewById(R.id.green_fill);
|
greenFill=contentView.findViewById(R.id.green_fill);
|
||||||
|
motionEffect.addViewEffect(new InterpolatingMotionEffect.ViewEffect(artClouds, V.dp(-5), V.dp(5), V.dp(-5), V.dp(5)));
|
||||||
|
motionEffect.addViewEffect(new InterpolatingMotionEffect.ViewEffect(artRightHill, V.dp(-15), V.dp(25), V.dp(-10), V.dp(10)));
|
||||||
|
motionEffect.addViewEffect(new InterpolatingMotionEffect.ViewEffect(artLeftHill, V.dp(-25), V.dp(15), V.dp(-15), V.dp(15)));
|
||||||
|
motionEffect.addViewEffect(new InterpolatingMotionEffect.ViewEffect(artCenterHill, V.dp(-14), V.dp(14), V.dp(-5), V.dp(25)));
|
||||||
|
motionEffect.addViewEffect(new InterpolatingMotionEffect.ViewEffect(artPlaneElephant, V.dp(-20), V.dp(12), V.dp(-20), V.dp(12)));
|
||||||
|
artContainer.setOnTouchListener(motionEffect);
|
||||||
|
|
||||||
contentView.setSizeListener(new SizeListenerFrameLayout.OnSizeChangedListener(){
|
contentView.setSizeListener(new SizeListenerFrameLayout.OnSizeChangedListener(){
|
||||||
@Override
|
@Override
|
||||||
@@ -109,6 +95,38 @@ public class SplashFragment extends AppKitFragment{
|
|||||||
Nav.go(getActivity(), isSignup ? InstanceCatalogSignupFragment.class : InstanceChooserLoginFragment.class, extras);
|
Nav.go(getActivity(), isSignup ? InstanceCatalogSignupFragment.class : InstanceChooserLoginFragment.class, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onJoinDefaultServerClick(View v){
|
||||||
|
new GetInstance()
|
||||||
|
.setCallback(new Callback<>(){
|
||||||
|
@Override
|
||||||
|
public void onSuccess(Instance result){
|
||||||
|
if(getActivity()==null)
|
||||||
|
return;
|
||||||
|
Bundle args=new Bundle();
|
||||||
|
args.putParcelable("instance", Parcels.wrap(result));
|
||||||
|
Nav.go(getActivity(), InstanceRulesFragment.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(ErrorResponse error){
|
||||||
|
if(getActivity()==null)
|
||||||
|
return;
|
||||||
|
error.showToast(getActivity());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.wrapProgress(getActivity(), R.string.loading_instance, true)
|
||||||
|
.execNoAuth(DEFAULT_SERVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onLearnMoreClick(View v){
|
||||||
|
View sheetView=getActivity().getLayoutInflater().inflate(R.layout.intro_bottom_sheet, null);
|
||||||
|
BottomSheet sheet=new BottomSheet(getActivity());
|
||||||
|
sheet.setContentView(sheetView);
|
||||||
|
sheet.setNavigationBarBackground(new ColorDrawable(UiUtils.alphaBlendColors(UiUtils.getThemeColor(getActivity(), R.attr.colorM3Surface),
|
||||||
|
UiUtils.getThemeColor(getActivity(), R.attr.colorM3Primary), 0.05f)), !UiUtils.isDarkTheme());
|
||||||
|
sheet.show();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateArtSize(int w, int h){
|
private void updateArtSize(int w, int h){
|
||||||
float scale=w/(float)V.dp(360);
|
float scale=w/(float)V.dp(360);
|
||||||
artContainer.setScaleX(scale);
|
artContainer.setScaleX(scale);
|
||||||
@@ -139,60 +157,15 @@ public class SplashFragment extends AppKitFragment{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PagerAdapter extends RecyclerView.Adapter<PagerViewHolder>{
|
@Override
|
||||||
|
protected void onShown(){
|
||||||
@NonNull
|
super.onShown();
|
||||||
@Override
|
motionEffect.activate();
|
||||||
public PagerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
|
||||||
return new PagerViewHolder(viewType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(@NonNull PagerViewHolder holder, int position){}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount(){
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemViewType(int position){
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PagerViewHolder extends RecyclerView.ViewHolder{
|
@Override
|
||||||
public PagerViewHolder(int page){
|
protected void onHidden(){
|
||||||
super(new LinearLayout(getActivity()));
|
super.onHidden();
|
||||||
LinearLayout ll=(LinearLayout) itemView;
|
motionEffect.deactivate();
|
||||||
ll.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
int pad=V.dp(16);
|
|
||||||
ll.setPadding(pad, pad, pad, pad);
|
|
||||||
ll.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
|
||||||
|
|
||||||
TextView title=new TextView(getActivity());
|
|
||||||
title.setTextAppearance(R.style.m3_headline_medium);
|
|
||||||
title.setText(switch(page){
|
|
||||||
case 0 -> getString(R.string.welcome_page1_title);
|
|
||||||
case 1 -> getString(R.string.welcome_page2_title);
|
|
||||||
case 2 -> getString(R.string.welcome_page3_title);
|
|
||||||
default -> throw new IllegalStateException("Unexpected value: "+page);
|
|
||||||
});
|
|
||||||
title.setTextColor(0xFF17063B);
|
|
||||||
LinearLayout.LayoutParams lp=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, V.dp(page==0 ? 46 : 36));
|
|
||||||
lp.bottomMargin=V.dp(page==0 ? 4 : 14);
|
|
||||||
ll.addView(title, lp);
|
|
||||||
|
|
||||||
TextView text=new TextView(getActivity());
|
|
||||||
text.setTextAppearance(R.style.m3_body_medium);
|
|
||||||
text.setText(switch(page){
|
|
||||||
case 0 -> R.string.welcome_page1_text;
|
|
||||||
case 1 -> R.string.welcome_page2_text;
|
|
||||||
case 2 -> R.string.welcome_page3_text;
|
|
||||||
default -> throw new IllegalStateException("Unexpected value: "+page);
|
|
||||||
});
|
|
||||||
text.setTextColor(0xFF17063B);
|
|
||||||
ll.addView(text, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import android.view.View;
|
|||||||
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.requests.statuses.GetStatusEditHistory;
|
import org.joinmastodon.android.api.requests.statuses.GetStatusEditHistory;
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.displayitems.ReblogOrReplyLineStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.ReblogOrReplyLineStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||||
@@ -55,7 +56,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||||
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false, null);
|
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false, null, null);
|
||||||
int idx=data.indexOf(s);
|
int idx=data.indexOf(s);
|
||||||
if(idx>=0){
|
if(idx>=0){
|
||||||
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));
|
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));
|
||||||
@@ -156,4 +157,9 @@ public class StatusEditHistoryFragment extends StatusListFragment{
|
|||||||
public boolean isItemEnabled(String id){
|
public boolean isItemEnabled(String id){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,11 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
|||||||
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
protected List<StatusDisplayItem> buildDisplayItems(Status s){
|
||||||
boolean addFooter = !GlobalUserPreferences.spectatorMode ||
|
boolean addFooter = !GlobalUserPreferences.spectatorMode ||
|
||||||
(this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id));
|
(this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id));
|
||||||
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, addFooter, null, Filter.FilterContext.HOME);
|
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, addFooter, null, getFilterContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected abstract Filter.FilterContext getFilterContext();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addAccountToKnown(Status s){
|
protected void addAccountToKnown(Status s){
|
||||||
if(!knownAccounts.containsKey(s.account.id))
|
if(!knownAccounts.containsKey(s.account.id))
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public class ThreadFragment extends StatusListFragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private List<Status> filterStatuses(List<Status> statuses){
|
private List<Status> filterStatuses(List<Status> statuses){
|
||||||
StatusFilterPredicate statusFilterPredicate=new StatusFilterPredicate(accountID,Filter.FilterContext.THREAD);
|
StatusFilterPredicate statusFilterPredicate=new StatusFilterPredicate(accountID,getFilterContext());
|
||||||
return statuses.stream()
|
return statuses.stream()
|
||||||
.filter(statusFilterPredicate)
|
.filter(statusFilterPredicate)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -181,4 +181,10 @@ public class ThreadFragment extends StatusListFragment{
|
|||||||
public boolean wantsLightNavigationBar(){
|
public boolean wantsLightNavigationBar(){
|
||||||
return !UiUtils.isDarkTheme();
|
return !UiUtils.isDarkTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.THREAD;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class DiscoverPostsFragment extends StatusListFragment implements IsOnTop
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<Status> result){
|
public void onSuccess(List<Status> result){
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
result=result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.PUBLIC)).collect(Collectors.toList());
|
result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList());
|
||||||
onDataLoaded(result, !result.isEmpty());
|
onDataLoaded(result, !result.isEmpty());
|
||||||
}
|
}
|
||||||
}).exec(accountID);
|
}).exec(accountID);
|
||||||
@@ -42,4 +42,10 @@ public class DiscoverPostsFragment extends StatusListFragment implements IsOnTop
|
|||||||
public boolean isOnTop() {
|
public boolean isOnTop() {
|
||||||
return isRecyclerViewOnTop(list);
|
return isRecyclerViewOnTop(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.PUBLIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class FederatedTimelineFragment extends StatusListFragment {
|
|||||||
private String maxID;
|
private String maxID;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ public class FederatedTimelineFragment extends StatusListFragment {
|
|||||||
if(!result.isEmpty())
|
if(!result.isEmpty())
|
||||||
maxID=result.get(result.size()-1).id;
|
maxID=result.get(result.size()-1).id;
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
result=result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.PUBLIC)).collect(Collectors.toList());
|
result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList());
|
||||||
onDataLoaded(result, !result.isEmpty());
|
onDataLoaded(result, !result.isEmpty());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -47,4 +47,9 @@ public class FederatedTimelineFragment extends StatusListFragment {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
bannerHelper.maybeAddBanner(contentWrap);
|
bannerHelper.maybeAddBanner(contentWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.PUBLIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class LocalTimelineFragment extends StatusListFragment {
|
|||||||
private String maxID;
|
private String maxID;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean withComposeButton() {
|
protected boolean wantsComposeButton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class LocalTimelineFragment extends StatusListFragment {
|
|||||||
if(!result.isEmpty())
|
if(!result.isEmpty())
|
||||||
maxID=result.get(result.size()-1).id;
|
maxID=result.get(result.size()-1).id;
|
||||||
if (getActivity() == null) return;
|
if (getActivity() == null) return;
|
||||||
result=result.stream().filter(new StatusFilterPredicate(accountID, Filter.FilterContext.PUBLIC)).collect(Collectors.toList());
|
result=result.stream().filter(new StatusFilterPredicate(accountID, getFilterContext())).collect(Collectors.toList());
|
||||||
onDataLoaded(result, !result.isEmpty());
|
onDataLoaded(result, !result.isEmpty());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -46,4 +46,9 @@ public class LocalTimelineFragment extends StatusListFragment {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
bannerHelper.maybeAddBanner(contentWrap);
|
bannerHelper.maybeAddBanner(contentWrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return Filter.FilterContext.PUBLIC;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.joinmastodon.android.fragments.IsOnTop;
|
|||||||
import org.joinmastodon.android.fragments.ProfileFragment;
|
import org.joinmastodon.android.fragments.ProfileFragment;
|
||||||
import org.joinmastodon.android.fragments.ThreadFragment;
|
import org.joinmastodon.android.fragments.ThreadFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.Hashtag;
|
import org.joinmastodon.android.model.Hashtag;
|
||||||
import org.joinmastodon.android.model.SearchResult;
|
import org.joinmastodon.android.model.SearchResult;
|
||||||
import org.joinmastodon.android.model.SearchResults;
|
import org.joinmastodon.android.model.SearchResults;
|
||||||
@@ -80,7 +81,7 @@ public class SearchFragment extends BaseStatusListFragment<SearchResult> impleme
|
|||||||
return switch(s.type){
|
return switch(s.type){
|
||||||
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
|
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
|
||||||
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
|
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
|
||||||
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true, null);
|
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true, null, Filter.FilterContext.PUBLIC);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.joinmastodon.android.api.requests.accounts.GetAccountStatuses;
|
|||||||
import org.joinmastodon.android.events.FinishReportFragmentsEvent;
|
import org.joinmastodon.android.events.FinishReportFragmentsEvent;
|
||||||
import org.joinmastodon.android.fragments.StatusListFragment;
|
import org.joinmastodon.android.fragments.StatusListFragment;
|
||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
|
import org.joinmastodon.android.model.Filter;
|
||||||
import org.joinmastodon.android.model.Status;
|
import org.joinmastodon.android.model.Status;
|
||||||
import org.joinmastodon.android.ui.displayitems.AudioStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.AudioStatusDisplayItem;
|
||||||
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
import org.joinmastodon.android.ui.displayitems.HeaderStatusDisplayItem;
|
||||||
@@ -261,4 +262,9 @@ public class ReportAddPostsChoiceFragment extends StatusListFragment{
|
|||||||
protected boolean wantsOverlaySystemNavigation(){
|
protected boolean wantsOverlaySystemNavigation(){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Filter.FilterContext getFilterContext() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package org.joinmastodon.android.model;
|
||||||
|
|
||||||
|
import android.view.Menu;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.R;
|
||||||
|
|
||||||
|
public enum ContentType {
|
||||||
|
@SerializedName("text/plain")
|
||||||
|
PLAIN,
|
||||||
|
@SerializedName("text/html")
|
||||||
|
HTML,
|
||||||
|
@SerializedName("text/markdown")
|
||||||
|
MARKDOWN,
|
||||||
|
@SerializedName("text/bbcode")
|
||||||
|
BBCODE, // akkoma
|
||||||
|
@SerializedName("text/x.misskeymarkdown")
|
||||||
|
MISSKEY_MARKDOWN; // akkoma/*key
|
||||||
|
|
||||||
|
public static int getContentTypeRes(@Nullable ContentType contentType) {
|
||||||
|
return contentType == null ? R.id.content_type_null : switch(contentType) {
|
||||||
|
case PLAIN -> R.id.content_type_plain;
|
||||||
|
case HTML -> R.id.content_type_html;
|
||||||
|
case MARKDOWN -> R.id.content_type_markdown;
|
||||||
|
case BBCODE -> R.id.content_type_bbcode;
|
||||||
|
case MISSKEY_MARKDOWN -> R.id.content_type_misskey_markdown;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void adaptMenuToInstance(Menu m, Instance i) {
|
||||||
|
if (i.pleroma == null) {
|
||||||
|
// memo: change this if glitch or another mastodon fork supports bbcode or mfm
|
||||||
|
m.findItem(R.id.content_type_bbcode).setVisible(false);
|
||||||
|
m.findItem(R.id.content_type_misskey_markdown).setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,22 +2,22 @@ package org.joinmastodon.android.model;
|
|||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
import org.joinmastodon.android.api.ObjectValidationException;
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
import org.joinmastodon.android.api.RequiredField;
|
|
||||||
import org.parceler.Parcel;
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Parcel
|
@Parcel
|
||||||
public class Filter extends BaseModel{
|
public class Filter extends BaseModel{
|
||||||
@RequiredField
|
|
||||||
public String id;
|
public String id;
|
||||||
@RequiredField
|
|
||||||
public String phrase;
|
public String phrase;
|
||||||
public String title;
|
public String title;
|
||||||
public transient EnumSet<FilterContext> context=EnumSet.noneOf(FilterContext.class);
|
public transient EnumSet<FilterContext> context=EnumSet.noneOf(FilterContext.class);
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
package org.joinmastodon.android.model;
|
package org.joinmastodon.android.model;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.api.ObjectValidationException;
|
||||||
import org.parceler.Parcel;
|
import org.parceler.Parcel;
|
||||||
|
|
||||||
@Parcel
|
@Parcel
|
||||||
public class FilterResult extends BaseModel {
|
public class FilterResult extends BaseModel {
|
||||||
public Filter filter;
|
public Filter filter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postprocess() throws ObjectValidationException {
|
||||||
|
super.postprocess();
|
||||||
|
if (filter != null) filter.postprocess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ public class Notification extends BaseModel implements DisplayItemsParent{
|
|||||||
public Account account;
|
public Account account;
|
||||||
public Status status;
|
public Status status;
|
||||||
public Report report;
|
public Report report;
|
||||||
|
public String emoji;
|
||||||
|
public String emojiUrl;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postprocess() throws ObjectValidationException{
|
public void postprocess() throws ObjectValidationException{
|
||||||
@@ -51,6 +53,10 @@ public class Notification extends BaseModel implements DisplayItemsParent{
|
|||||||
STATUS,
|
STATUS,
|
||||||
@SerializedName("update")
|
@SerializedName("update")
|
||||||
UPDATE,
|
UPDATE,
|
||||||
|
@SerializedName("reaction")
|
||||||
|
REACTION,
|
||||||
|
@SerializedName("pleroma:emoji_reaction")
|
||||||
|
PLEROMA_EMOJI_REACTION,
|
||||||
@SerializedName("admin.sign_up")
|
@SerializedName("admin.sign_up")
|
||||||
SIGN_UP,
|
SIGN_UP,
|
||||||
@SerializedName("admin.report")
|
@SerializedName("admin.report")
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public class ScheduledStatus extends BaseModel implements DisplayItemsParent{
|
|||||||
public String idempotency;
|
public String idempotency;
|
||||||
public String applicationId;
|
public String applicationId;
|
||||||
public List<String> mediaIds;
|
public List<String> mediaIds;
|
||||||
|
public ContentType contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parcel
|
@Parcel
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ public class Status extends BaseModel implements DisplayItemsParent, Searchable{
|
|||||||
card.postprocess();
|
card.postprocess();
|
||||||
if(reblog!=null)
|
if(reblog!=null)
|
||||||
reblog.postprocess();
|
reblog.postprocess();
|
||||||
|
if(filtered!=null)
|
||||||
|
for(FilterResult fr : filtered)
|
||||||
|
fr.postprocess();
|
||||||
|
|
||||||
spoilerRevealed=GlobalUserPreferences.alwaysExpandContentWarnings || !sensitive;
|
spoilerRevealed=GlobalUserPreferences.alwaysExpandContentWarnings || !sensitive;
|
||||||
if (visibility.equals(StatusPrivacy.LOCAL)) localOnly = true;
|
if (visibility.equals(StatusPrivacy.LOCAL)) localOnly = true;
|
||||||
|
|||||||
@@ -1,17 +1,25 @@
|
|||||||
package org.joinmastodon.android.ui;
|
package org.joinmastodon.android.ui;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
import android.view.animation.PathInterpolator;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class InterpolatingMotionEffect implements SensorEventListener{
|
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||||
|
import androidx.dynamicanimation.animation.FloatValueHolder;
|
||||||
|
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||||
|
import androidx.dynamicanimation.animation.SpringForce;
|
||||||
|
|
||||||
|
public class InterpolatingMotionEffect implements SensorEventListener, View.OnTouchListener{
|
||||||
|
|
||||||
private SensorManager sm;
|
private SensorManager sm;
|
||||||
private WindowManager wm;
|
private WindowManager wm;
|
||||||
@@ -20,6 +28,34 @@ public class InterpolatingMotionEffect implements SensorEventListener{
|
|||||||
private Sensor accelerometer;
|
private Sensor accelerometer;
|
||||||
private boolean accelerometerEnabled;
|
private boolean accelerometerEnabled;
|
||||||
private ArrayList<ViewEffect> views=new ArrayList<>();
|
private ArrayList<ViewEffect> views=new ArrayList<>();
|
||||||
|
private float pitch, roll;
|
||||||
|
private float touchDownX, touchDownY, touchAddX, touchAddY, touchAddLastAnimX, touchAddLastAnimY;
|
||||||
|
private PathInterpolator touchInterpolator=new PathInterpolator(0.5f, 1f, 0.89f, 1f);
|
||||||
|
private SpringAnimation touchSpringX, touchSpringY;
|
||||||
|
private FloatValueHolder touchSpringXHolder=new FloatValueHolder(){
|
||||||
|
@Override
|
||||||
|
public float getValue(){
|
||||||
|
return touchAddX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(float value){
|
||||||
|
touchAddX=value;
|
||||||
|
updateEffects();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private FloatValueHolder touchSpringYHolder=new FloatValueHolder(){
|
||||||
|
@Override
|
||||||
|
public float getValue(){
|
||||||
|
return touchAddY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setValue(float value){
|
||||||
|
touchAddY=value;
|
||||||
|
updateEffects();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public InterpolatingMotionEffect(Context context){
|
public InterpolatingMotionEffect(Context context){
|
||||||
sm=context.getSystemService(SensorManager.class);
|
sm=context.getSystemService(SensorManager.class);
|
||||||
@@ -50,8 +86,8 @@ public class InterpolatingMotionEffect implements SensorEventListener{
|
|||||||
float z=event.values[2]/SensorManager.GRAVITY_EARTH;
|
float z=event.values[2]/SensorManager.GRAVITY_EARTH;
|
||||||
|
|
||||||
|
|
||||||
float pitch=(float) (Math.atan2(x, Math.sqrt(y*y+z*z))/Math.PI*2.0);
|
pitch=(float) (Math.atan2(x, Math.sqrt(y*y+z*z))/Math.PI*2.0);
|
||||||
float roll=(float) (Math.atan2(y, Math.sqrt(x*x+z*z))/Math.PI*2.0);
|
roll=(float) (Math.atan2(y, Math.sqrt(x*x+z*z))/Math.PI*2.0);
|
||||||
|
|
||||||
switch(rotation){
|
switch(rotation){
|
||||||
case Surface.ROTATION_0:
|
case Surface.ROTATION_0:
|
||||||
@@ -88,9 +124,7 @@ public class InterpolatingMotionEffect implements SensorEventListener{
|
|||||||
}else if(roll<-1f){
|
}else if(roll<-1f){
|
||||||
roll=-2f-roll;
|
roll=-2f-roll;
|
||||||
}
|
}
|
||||||
for(ViewEffect view:views){
|
updateEffects();
|
||||||
view.update(pitch, roll);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -110,6 +144,62 @@ public class InterpolatingMotionEffect implements SensorEventListener{
|
|||||||
views.clear();
|
views.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent ev){
|
||||||
|
switch(ev.getAction()){
|
||||||
|
case MotionEvent.ACTION_DOWN -> {
|
||||||
|
if(touchSpringX!=null){
|
||||||
|
touchAddLastAnimX=touchAddX;
|
||||||
|
touchSpringX.cancel();
|
||||||
|
touchSpringX=null;
|
||||||
|
}else{
|
||||||
|
touchAddLastAnimX=0;
|
||||||
|
}
|
||||||
|
if(touchSpringY!=null){
|
||||||
|
touchAddLastAnimY=touchAddY;
|
||||||
|
touchSpringY.cancel();
|
||||||
|
touchSpringY=null;
|
||||||
|
}else{
|
||||||
|
touchAddLastAnimY=0;
|
||||||
|
}
|
||||||
|
touchDownX=ev.getX();
|
||||||
|
touchDownY=ev.getY();
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_MOVE -> {
|
||||||
|
touchAddX=touchInterpolator.getInterpolation(Math.min(1f, Math.abs((ev.getX()-touchDownX)/(v.getWidth()/2f))));
|
||||||
|
touchAddY=touchInterpolator.getInterpolation(Math.min(1f, Math.abs((ev.getY()-touchDownY)/(v.getHeight()/2f))));
|
||||||
|
if(ev.getX()>touchDownX)
|
||||||
|
touchAddX=-touchAddX;
|
||||||
|
if(ev.getY()<touchDownY)
|
||||||
|
touchAddY=-touchAddY;
|
||||||
|
touchAddX+=touchAddLastAnimX;
|
||||||
|
touchAddY+=touchAddLastAnimY;
|
||||||
|
updateEffects();
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||||
|
touchSpringX=new SpringAnimation(touchSpringXHolder, 0f);
|
||||||
|
touchSpringX.setMinimumVisibleChange(0.01f);
|
||||||
|
touchSpringX.getSpring().setStiffness(SpringForce.STIFFNESS_LOW).setDampingRatio(0.85f);
|
||||||
|
touchSpringX.addEndListener((animation, canceled, value, velocity)->touchSpringX=null);
|
||||||
|
touchSpringX.start();
|
||||||
|
touchSpringY=new SpringAnimation(touchSpringYHolder, 0f);
|
||||||
|
touchSpringY.setMinimumVisibleChange(0.01f);
|
||||||
|
touchSpringY.getSpring().setStiffness(SpringForce.STIFFNESS_LOW).setDampingRatio(0.85f);
|
||||||
|
touchSpringY.addEndListener((animation, canceled, value, velocity)->touchSpringY=null);
|
||||||
|
touchSpringY.start();
|
||||||
|
updateEffects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateEffects(){
|
||||||
|
for(ViewEffect view:views){
|
||||||
|
view.update(Math.min(1f, Math.max(-1f, pitch+touchAddX)), Math.min(1f, Math.max(-1f, roll+touchAddY)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ViewEffect{
|
public static class ViewEffect{
|
||||||
private View view;
|
private View view;
|
||||||
private float minX, maxX, minY, maxY;
|
private float minX, maxX, minY, maxY;
|
||||||
|
|||||||
@@ -200,6 +200,11 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onBoostClick(View v){
|
private void onBoostClick(View v){
|
||||||
|
if (GlobalUserPreferences.confirmBeforeReblog) {
|
||||||
|
v.startAnimation(opacityIn);
|
||||||
|
onBoostLongClick(v);
|
||||||
|
return;
|
||||||
|
}
|
||||||
boost.setSelected(!item.status.reblogged);
|
boost.setSelected(!item.status.reblogged);
|
||||||
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(item.status, !item.status.reblogged, null, r->boostConsumer(v, r));
|
AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(item.status, !item.status.reblogged, null, r->boostConsumer(v, r));
|
||||||
}
|
}
|
||||||
@@ -235,9 +240,9 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
reblogHeader.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
reblogHeader.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||||
reblogAs.setVisibility(AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1 ? View.VISIBLE : View.GONE);
|
reblogAs.setVisibility(AccountSessionManager.getInstance().getLoggedInAccounts().size() > 1 ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
itemPublic.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.PUBLIC) ? View.GONE : View.VISIBLE);
|
itemPublic.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||||
itemUnlisted.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.UNLISTED) ? View.GONE : View.VISIBLE);
|
itemUnlisted.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||||
itemFollowers.setVisibility(item.status.reblogged || item.status.visibility.isLessVisibleThan(StatusPrivacy.PRIVATE) ? View.GONE : View.VISIBLE);
|
itemFollowers.setVisibility(item.status.reblogged ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
Drawable checkMark = ctx.getDrawable(R.drawable.ic_fluent_checkmark_circle_20_regular);
|
Drawable checkMark = ctx.getDrawable(R.drawable.ic_fluent_checkmark_circle_20_regular);
|
||||||
Drawable publicDrawable = ctx.getDrawable(R.drawable.ic_fluent_earth_24_regular);
|
Drawable publicDrawable = ctx.getDrawable(R.drawable.ic_fluent_earth_24_regular);
|
||||||
@@ -245,16 +250,6 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{
|
|||||||
Drawable followersDrawable = ctx.getDrawable(R.drawable.ic_fluent_lock_closed_24_regular);
|
Drawable followersDrawable = ctx.getDrawable(R.drawable.ic_fluent_lock_closed_24_regular);
|
||||||
|
|
||||||
StatusPrivacy defaultVisibility = session.preferences != null ? session.preferences.postingDefaultVisibility : null;
|
StatusPrivacy defaultVisibility = session.preferences != null ? session.preferences.postingDefaultVisibility : null;
|
||||||
// e.g. post visibility is unlisted, but default is public
|
|
||||||
// in this case, we want to display the check mark on the most visible visibility
|
|
||||||
if (defaultVisibility != null && item.status.visibility.isLessVisibleThan(defaultVisibility)) {
|
|
||||||
for (StatusPrivacy vis : StatusPrivacy.values()) {
|
|
||||||
if (vis.equals(item.status.visibility)) {
|
|
||||||
defaultVisibility = vis;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
itemPublic.setCompoundDrawablesWithIntrinsicBounds(publicDrawable, null, StatusPrivacy.PUBLIC.equals(defaultVisibility) ? checkMark : null, null);
|
itemPublic.setCompoundDrawablesWithIntrinsicBounds(publicDrawable, null, StatusPrivacy.PUBLIC.equals(defaultVisibility) ? checkMark : null, null);
|
||||||
itemUnlisted.setCompoundDrawablesWithIntrinsicBounds(unlistedDrawable, null, StatusPrivacy.UNLISTED.equals(defaultVisibility) ? checkMark : null, null);
|
itemUnlisted.setCompoundDrawablesWithIntrinsicBounds(unlistedDrawable, null, StatusPrivacy.UNLISTED.equals(defaultVisibility) ? checkMark : null, null);
|
||||||
itemFollowers.setCompoundDrawablesWithIntrinsicBounds(followersDrawable, null, StatusPrivacy.PRIVATE.equals(defaultVisibility) ? checkMark : null, null);
|
itemFollowers.setCompoundDrawablesWithIntrinsicBounds(followersDrawable, null, StatusPrivacy.PRIVATE.equals(defaultVisibility) ? checkMark : null, null);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
|
|||||||
import org.joinmastodon.android.model.Account;
|
import org.joinmastodon.android.model.Account;
|
||||||
import org.joinmastodon.android.model.Announcement;
|
import org.joinmastodon.android.model.Announcement;
|
||||||
import org.joinmastodon.android.model.Attachment;
|
import org.joinmastodon.android.model.Attachment;
|
||||||
|
import org.joinmastodon.android.model.ContentType;
|
||||||
import org.joinmastodon.android.model.Notification;
|
import org.joinmastodon.android.model.Notification;
|
||||||
import org.joinmastodon.android.model.Relationship;
|
import org.joinmastodon.android.model.Relationship;
|
||||||
import org.joinmastodon.android.model.ScheduledStatus;
|
import org.joinmastodon.android.model.ScheduledStatus;
|
||||||
@@ -83,13 +84,13 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
public final Status status;
|
public final Status status;
|
||||||
private boolean hasVisibilityToggle;
|
private boolean hasVisibilityToggle;
|
||||||
boolean needBottomPadding;
|
boolean needBottomPadding;
|
||||||
private String extraText;
|
private CharSequence extraText;
|
||||||
private Notification notification;
|
private Notification notification;
|
||||||
private ScheduledStatus scheduledStatus;
|
private ScheduledStatus scheduledStatus;
|
||||||
private Announcement announcement;
|
private Announcement announcement;
|
||||||
private Consumer<String> consumeReadAnnouncement;
|
private Consumer<String> consumeReadAnnouncement;
|
||||||
|
|
||||||
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, String extraText, Notification notification, ScheduledStatus scheduledStatus){
|
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, CharSequence extraText, Notification notification, ScheduledStatus scheduledStatus){
|
||||||
super(parentID, parentFragment);
|
super(parentID, parentFragment);
|
||||||
user=scheduledStatus != null ? AccountSessionManager.getInstance().getAccount(accountID).self : user;
|
user=scheduledStatus != null ? AccountSessionManager.getInstance().getAccount(accountID).self : user;
|
||||||
this.user=user;
|
this.user=user;
|
||||||
@@ -114,6 +115,7 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.extraText=extraText;
|
this.extraText=extraText;
|
||||||
|
emojiHelper.addText(extraText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HeaderStatusDisplayItem fromAnnouncement(Announcement a, Status fakeStatus, Account instanceUser, BaseStatusListFragment parentFragment, String accountID, Consumer<String> consumeReadID) {
|
public static HeaderStatusDisplayItem fromAnnouncement(Announcement a, Status fakeStatus, Account instanceUser, BaseStatusListFragment parentFragment, String accountID, Consumer<String> consumeReadID) {
|
||||||
@@ -216,6 +218,9 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
|
|||||||
public void onSuccess(GetStatusSourceText.Response result){
|
public void onSuccess(GetStatusSourceText.Response result){
|
||||||
args.putString("sourceText", result.text);
|
args.putString("sourceText", result.text);
|
||||||
args.putString("sourceSpoiler", result.spoilerText);
|
args.putString("sourceSpoiler", result.spoilerText);
|
||||||
|
if (result.contentType != null) {
|
||||||
|
args.putString("sourceContentType", result.contentType.name());
|
||||||
|
}
|
||||||
if (redraft) {
|
if (redraft) {
|
||||||
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{
|
UiUtils.confirmDeletePost(item.parentFragment.getActivity(), item.parentFragment.getAccountID(), item.status, s->{
|
||||||
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
Nav.go(item.parentFragment.getActivity(), ComposeFragment.class, args);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.joinmastodon.android.ui.displayitems;
|
package org.joinmastodon.android.ui.displayitems;
|
||||||
|
|
||||||
import static org.joinmastodon.android.ui.utils.MediaAttachmentViewController.altWrapPadding;
|
import static org.joinmastodon.android.GlobalUserPreferences.*;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
@@ -55,7 +55,7 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|||||||
for(Attachment att:attachments){
|
for(Attachment att:attachments){
|
||||||
requests.add(new UrlImageLoaderRequest(switch(att.type){
|
requests.add(new UrlImageLoaderRequest(switch(att.type){
|
||||||
case IMAGE -> att.url;
|
case IMAGE -> att.url;
|
||||||
case VIDEO, GIFV -> att.previewUrl;
|
case VIDEO, GIFV -> att.previewUrl != null ? att.previewUrl : att.url;
|
||||||
default -> throw new IllegalStateException("Unexpected value: "+att.type);
|
default -> throw new IllegalStateException("Unexpected value: "+att.type);
|
||||||
}, 1000, 1000));
|
}, 1000, 1000));
|
||||||
}
|
}
|
||||||
@@ -183,10 +183,11 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|||||||
altTextIndex=index;
|
altTextIndex=index;
|
||||||
Attachment att=item.attachments.get(index);
|
Attachment att=item.attachments.get(index);
|
||||||
boolean hasAltText = !TextUtils.isEmpty(att.description);
|
boolean hasAltText = !TextUtils.isEmpty(att.description);
|
||||||
altTextButton.setVisibility(hasAltText && GlobalUserPreferences.showAltIndicator ? View.VISIBLE : View.GONE);
|
if ((hasAltText && !showAltIndicator) || (!hasAltText && !showNoAltIndicator)) return;
|
||||||
noAltTextButton.setVisibility(!hasAltText && GlobalUserPreferences.showNoAltIndicator ? View.VISIBLE : View.GONE);
|
altTextButton.setVisibility(hasAltText && showAltIndicator ? View.VISIBLE : View.GONE);
|
||||||
altText.setVisibility(hasAltText && GlobalUserPreferences.showAltIndicator ? View.VISIBLE : View.GONE);
|
noAltTextButton.setVisibility(!hasAltText && showNoAltIndicator ? View.VISIBLE : View.GONE);
|
||||||
noAltText.setVisibility(!hasAltText && GlobalUserPreferences.showNoAltIndicator ? View.VISIBLE : View.GONE);
|
altText.setVisibility(hasAltText && showAltIndicator ? View.VISIBLE : View.GONE);
|
||||||
|
noAltText.setVisibility(!hasAltText && showNoAltIndicator ? View.VISIBLE : View.GONE);
|
||||||
altText.setText(att.description);
|
altText.setText(att.description);
|
||||||
altTextWrapper.setVisibility(View.VISIBLE);
|
altTextWrapper.setVisibility(View.VISIBLE);
|
||||||
altTextWrapper.setBackgroundResource(hasAltText ? R.drawable.bg_image_alt_overlay : R.drawable.bg_image_no_alt_overlay);
|
altTextWrapper.setBackgroundResource(hasAltText ? R.drawable.bg_image_alt_overlay : R.drawable.bg_image_no_alt_overlay);
|
||||||
@@ -202,15 +203,16 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|||||||
btnL-=loc[0];
|
btnL-=loc[0];
|
||||||
btnT-=loc[1];
|
btnT-=loc[1];
|
||||||
|
|
||||||
|
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) altTextWrapper.getLayoutParams();
|
||||||
ArrayList<Animator> anims=new ArrayList<>();
|
ArrayList<Animator> anims=new ArrayList<>();
|
||||||
anims.add(ObjectAnimator.ofFloat(altTextButton, View.ALPHA, 1, 0));
|
anims.add(ObjectAnimator.ofFloat(altTextButton, View.ALPHA, 1, 0));
|
||||||
anims.add(ObjectAnimator.ofFloat(noAltTextButton, View.ALPHA, 1, 0));
|
anims.add(ObjectAnimator.ofFloat(noAltTextButton, View.ALPHA, 1, 0));
|
||||||
anims.add(ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, 0, 1));
|
anims.add(ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, 0, 1));
|
||||||
anims.add(ObjectAnimator.ofFloat(altTextClose, View.ALPHA, 0, 1));
|
anims.add(ObjectAnimator.ofFloat(altTextClose, View.ALPHA, 0, 1));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "left", btnL+altWrapPadding[0], altTextWrapper.getLeft()));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "left", btnL+margins.leftMargin, altTextWrapper.getLeft()));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "top", btnT+altWrapPadding[1], altTextWrapper.getTop()));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "top", btnT+margins.topMargin, altTextWrapper.getTop()));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "right", btnL+v.getWidth()-altWrapPadding[2], altTextWrapper.getRight()));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "right", btnL+v.getWidth()-margins.rightMargin, altTextWrapper.getRight()));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "bottom", btnT+v.getHeight()-altWrapPadding[3], altTextWrapper.getBottom()));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "bottom", btnT+v.getHeight()-margins.bottomMargin, altTextWrapper.getBottom()));
|
||||||
for(Animator a:anims)
|
for(Animator a:anims)
|
||||||
a.setDuration(300);
|
a.setDuration(300);
|
||||||
|
|
||||||
@@ -249,8 +251,11 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|||||||
View btn=controllers.get(altTextIndex).btnsWrap;
|
View btn=controllers.get(altTextIndex).btnsWrap;
|
||||||
int i=0;
|
int i=0;
|
||||||
for(MediaAttachmentViewController c:controllers){
|
for(MediaAttachmentViewController c:controllers){
|
||||||
if(c.btnsWrap!=null && c.btnsWrap!=btn && !TextUtils.isEmpty(item.attachments.get(i).description))
|
boolean hasAltText = !TextUtils.isEmpty(item.attachments.get(i).description);
|
||||||
c.btnsWrap.setVisibility(View.VISIBLE);
|
if(c.btnsWrap!=null
|
||||||
|
&& c.btnsWrap!=btn
|
||||||
|
&& ((hasAltText && showAltIndicator) || (!hasAltText && showNoAltIndicator))
|
||||||
|
) c.btnsWrap.setVisibility(View.VISIBLE);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,15 +266,16 @@ public class MediaGridStatusDisplayItem extends StatusDisplayItem{
|
|||||||
btnL-=loc[0];
|
btnL-=loc[0];
|
||||||
btnT-=loc[1];
|
btnT-=loc[1];
|
||||||
|
|
||||||
|
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) altTextWrapper.getLayoutParams();
|
||||||
ArrayList<Animator> anims=new ArrayList<>();
|
ArrayList<Animator> anims=new ArrayList<>();
|
||||||
anims.add(ObjectAnimator.ofFloat(altTextButton, View.ALPHA, 1));
|
anims.add(ObjectAnimator.ofFloat(altTextButton, View.ALPHA, 1));
|
||||||
anims.add(ObjectAnimator.ofFloat(noAltTextButton, View.ALPHA, 1));
|
anims.add(ObjectAnimator.ofFloat(noAltTextButton, View.ALPHA, 1));
|
||||||
anims.add(ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, 0));
|
anims.add(ObjectAnimator.ofFloat(altTextScroller, View.ALPHA, 0));
|
||||||
anims.add(ObjectAnimator.ofFloat(altTextClose, View.ALPHA, 0));
|
anims.add(ObjectAnimator.ofFloat(altTextClose, View.ALPHA, 0));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "left", btnL+altWrapPadding[0]));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "left", btnL+margins.leftMargin));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "top", btnT+altWrapPadding[1]));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "top", btnT+margins.topMargin));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "right", btnL+btn.getWidth()-altWrapPadding[2]));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "right", btnL+btn.getWidth()-margins.rightMargin));
|
||||||
anims.add(ObjectAnimator.ofInt(altTextWrapper, "bottom", btnT+btn.getHeight()-altWrapPadding[3]));
|
anims.add(ObjectAnimator.ofInt(altTextWrapper, "bottom", btnT+btn.getHeight()-margins.bottomMargin));
|
||||||
for(Animator a:anims)
|
for(Animator a:anims)
|
||||||
a.setDuration(300);
|
a.setDuration(300);
|
||||||
|
|
||||||
|
|||||||
@@ -81,18 +81,10 @@ public abstract class StatusDisplayItem{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification){
|
|
||||||
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, Filter.FilterContext.HOME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, Filter.FilterContext filterContext){
|
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, Filter.FilterContext filterContext){
|
||||||
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, filterContext);
|
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, false, filterContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate){
|
|
||||||
return buildItems(fragment, status, accountID, parentObject, knownAccounts, inset, addFooter, notification, disableTranslate, Filter.FilterContext.HOME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate, Filter.FilterContext filterContext){
|
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment<?> fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification, boolean disableTranslate, Filter.FilterContext filterContext){
|
||||||
String parentID=parentObject.getID();
|
String parentID=parentObject.getID();
|
||||||
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
ArrayList<StatusDisplayItem> items=new ArrayList<>();
|
||||||
@@ -102,12 +94,8 @@ public abstract class StatusDisplayItem{
|
|||||||
args.putString("account", accountID);
|
args.putString("account", accountID);
|
||||||
ScheduledStatus scheduledStatus = parentObject instanceof ScheduledStatus ? (ScheduledStatus) parentObject : null;
|
ScheduledStatus scheduledStatus = parentObject instanceof ScheduledStatus ? (ScheduledStatus) parentObject : null;
|
||||||
|
|
||||||
List<Filter> filters = AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream()
|
if (!statusForContent.filterRevealed) {
|
||||||
.filter(f -> f.context.contains(filterContext)).collect(Collectors.toList());
|
statusForContent.filterRevealed = new StatusFilterPredicate(accountID, filterContext, Filter.FilterAction.WARN).test(status);
|
||||||
StatusFilterPredicate filterPredicate = new StatusFilterPredicate(filters);
|
|
||||||
|
|
||||||
if(!statusForContent.filterRevealed){
|
|
||||||
statusForContent.filterRevealed = filterPredicate.testWithWarning(status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReblogOrReplyLineStatusDisplayItem replyLine = null;
|
ReblogOrReplyLineStatusDisplayItem replyLine = null;
|
||||||
@@ -201,8 +189,6 @@ public abstract class StatusDisplayItem{
|
|||||||
}
|
}
|
||||||
if(addFooter){
|
if(addFooter){
|
||||||
items.add(new FooterStatusDisplayItem(parentID, fragment, statusForContent, accountID));
|
items.add(new FooterStatusDisplayItem(parentID, fragment, statusForContent, accountID));
|
||||||
if(status.hasGapAfter && !(fragment instanceof ThreadFragment))
|
|
||||||
items.add(new GapStatusDisplayItem(parentID, fragment));
|
|
||||||
}
|
}
|
||||||
int i=1;
|
int i=1;
|
||||||
for(StatusDisplayItem item:items){
|
for(StatusDisplayItem item:items){
|
||||||
@@ -210,13 +196,16 @@ public abstract class StatusDisplayItem{
|
|||||||
item.index=i++;
|
item.index=i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!statusForContent.filterRevealed) {
|
ArrayList<StatusDisplayItem> result = statusForContent.filterRevealed ? items :
|
||||||
return new ArrayList<>(List.of(
|
new ArrayList<>(List.of(new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items)));
|
||||||
new WarningFilteredStatusDisplayItem(parentID, fragment, statusForContent, items)
|
|
||||||
));
|
if (addFooter && status.hasGapAfter && !(fragment instanceof ThreadFragment)) {
|
||||||
|
StatusDisplayItem gap = new GapStatusDisplayItem(parentID, fragment);
|
||||||
|
gap.index = i++;
|
||||||
|
result.add(gap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void buildPollItems(String parentID, BaseStatusListFragment fragment, Poll poll, List<StatusDisplayItem> items){
|
public static void buildPollItems(String parentID, BaseStatusListFragment fragment, Poll poll, List<StatusDisplayItem> items){
|
||||||
|
|||||||
@@ -29,6 +29,16 @@ public class CustomEmojiHelper{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addText(CharSequence text) {
|
||||||
|
if(!(text instanceof Spanned))
|
||||||
|
return;
|
||||||
|
CustomEmojiSpan[] spans=((Spanned) text).getSpans(0, text.length(), CustomEmojiSpan.class);
|
||||||
|
for(List<CustomEmojiSpan> group:Arrays.stream(spans).collect(Collectors.groupingBy(s->s.emoji)).values()){
|
||||||
|
this.spans.add(group);
|
||||||
|
requests.add(group.get(0).createImageLoaderRequest());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int getImageCount(){
|
public int getImageCount(){
|
||||||
return requests.size();
|
return requests.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ public class MediaAttachmentViewController{
|
|||||||
public final MediaGridStatusDisplayItem.GridItemType type;
|
public final MediaGridStatusDisplayItem.GridItemType type;
|
||||||
public final ImageView photo;
|
public final ImageView photo;
|
||||||
public final View altButton, noAltButton, btnsWrap;
|
public final View altButton, noAltButton, btnsWrap;
|
||||||
public static int[] altWrapPadding = null;
|
|
||||||
private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable();
|
private BlurhashCrossfadeDrawable crossfadeDrawable=new BlurhashCrossfadeDrawable();
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private boolean didClear;
|
private boolean didClear;
|
||||||
@@ -37,9 +36,6 @@ public class MediaAttachmentViewController{
|
|||||||
btnsWrap=view.findViewById(R.id.alt_badges);
|
btnsWrap=view.findViewById(R.id.alt_badges);
|
||||||
this.type=type;
|
this.type=type;
|
||||||
this.context=context;
|
this.context=context;
|
||||||
if (altWrapPadding == null) {
|
|
||||||
altWrapPadding = new int[] { btnsWrap.getPaddingLeft(), btnsWrap.getPaddingTop(), btnsWrap.getPaddingRight(), btnsWrap.getPaddingBottom() };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(Attachment attachment, Status status){
|
public void bind(Attachment attachment, Status status){
|
||||||
|
|||||||
@@ -137,10 +137,15 @@ public class UiUtils {
|
|||||||
private static Handler mainHandler = new Handler(Looper.getMainLooper());
|
private static Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
private static final DateTimeFormatter DATE_FORMATTER_SHORT_WITH_YEAR = DateTimeFormatter.ofPattern("d MMM uuuu"), DATE_FORMATTER_SHORT = DateTimeFormatter.ofPattern("d MMM");
|
private static final DateTimeFormatter DATE_FORMATTER_SHORT_WITH_YEAR = DateTimeFormatter.ofPattern("d MMM uuuu"), DATE_FORMATTER_SHORT = DateTimeFormatter.ofPattern("d MMM");
|
||||||
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT);
|
public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT);
|
||||||
|
public static int MAX_WIDTH;
|
||||||
|
|
||||||
private UiUtils() {
|
private UiUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void loadMaxWidth(Context ctx) {
|
||||||
|
if (MAX_WIDTH == 0) MAX_WIDTH = (int) ctx.getResources().getDimension(R.dimen.layout_max_width);
|
||||||
|
}
|
||||||
|
|
||||||
public static void launchWebBrowser(Context context, String url) {
|
public static void launchWebBrowser(Context context, String url) {
|
||||||
try {
|
try {
|
||||||
if (GlobalUserPreferences.useCustomTabs) {
|
if (GlobalUserPreferences.useCustomTabs) {
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ package org.joinmastodon.android.ui.views;
|
|||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class ComposeMediaLayout extends ViewGroup{
|
public class ComposeMediaLayout extends ViewGroup{
|
||||||
private static final int MAX_WIDTH_DP=400;
|
|
||||||
private static final int GAP_DP=8;
|
private static final int GAP_DP=8;
|
||||||
private static final float ASPECT_RATIO=0.5625f;
|
private static final float ASPECT_RATIO=0.5625f;
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ public class ComposeMediaLayout extends ViewGroup{
|
|||||||
|
|
||||||
public ComposeMediaLayout(Context context, AttributeSet attrs, int defStyle){
|
public ComposeMediaLayout(Context context, AttributeSet attrs, int defStyle){
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
UiUtils.loadMaxWidth(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -30,7 +31,7 @@ public class ComposeMediaLayout extends ViewGroup{
|
|||||||
int mode=MeasureSpec.getMode(widthMeasureSpec);
|
int mode=MeasureSpec.getMode(widthMeasureSpec);
|
||||||
@SuppressLint("SwitchIntDef")
|
@SuppressLint("SwitchIntDef")
|
||||||
int width=switch(mode){
|
int width=switch(mode){
|
||||||
case MeasureSpec.AT_MOST -> Math.min(V.dp(MAX_WIDTH_DP), MeasureSpec.getSize(widthMeasureSpec));
|
case MeasureSpec.AT_MOST -> Math.min(UiUtils.MAX_WIDTH, MeasureSpec.getSize(widthMeasureSpec));
|
||||||
case MeasureSpec.EXACTLY -> MeasureSpec.getSize(widthMeasureSpec);
|
case MeasureSpec.EXACTLY -> MeasureSpec.getSize(widthMeasureSpec);
|
||||||
default -> throw new IllegalArgumentException("unsupported measure mode");
|
default -> throw new IllegalArgumentException("unsupported measure mode");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import android.view.View;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A LinearLayout for TextViews. First child TextView will get truncated if it doesn't fit, remaining will always wrap content.
|
* A LinearLayout for TextViews. First child TextView will get truncated if it doesn't fit, remaining will always wrap content.
|
||||||
*/
|
*/
|
||||||
@@ -36,7 +38,8 @@ public class HeaderSubtitleLinearLayout extends LinearLayout{
|
|||||||
}
|
}
|
||||||
View first=getChildAt(0);
|
View first=getChildAt(0);
|
||||||
if(first instanceof TextView){
|
if(first instanceof TextView){
|
||||||
((TextView) first).setMaxWidth(remainingWidth);
|
// guaranteeing at least 64dp of width for the display name
|
||||||
|
((TextView) first).setMaxWidth(Math.max(remainingWidth, V.dp(64)));
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
View first=getChildAt(0);
|
View first=getChildAt(0);
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
import org.joinmastodon.android.ui.PhotoLayoutHelper;
|
||||||
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
|
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class MediaGridLayout extends ViewGroup{
|
public class MediaGridLayout extends ViewGroup{
|
||||||
private static final String TAG="MediaGridLayout";
|
private static final String TAG="MediaGridLayout";
|
||||||
|
|
||||||
public static final int MAX_WIDTH=400; // dp
|
|
||||||
private static final int GAP=1; // dp
|
private static final int GAP=1; // dp
|
||||||
private PhotoLayoutHelper.TiledLayoutResult tiledLayout;
|
private PhotoLayoutHelper.TiledLayoutResult tiledLayout;
|
||||||
private int[] columnStarts=new int[10], columnEnds=new int[10], rowStarts=new int[10], rowEnds=new int[10];
|
private int[] columnStarts=new int[10], columnEnds=new int[10], rowStarts=new int[10], rowEnds=new int[10];
|
||||||
@@ -27,7 +27,7 @@ public class MediaGridLayout extends ViewGroup{
|
|||||||
|
|
||||||
public MediaGridLayout(Context context, AttributeSet attrs, int defStyle){
|
public MediaGridLayout(Context context, AttributeSet attrs, int defStyle){
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
UiUtils.loadMaxWidth(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -36,7 +36,7 @@ public class MediaGridLayout extends ViewGroup{
|
|||||||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), 0);
|
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int width=Math.min(V.dp(MAX_WIDTH), MeasureSpec.getSize(widthMeasureSpec));
|
int width=Math.min(UiUtils.MAX_WIDTH, MeasureSpec.getSize(widthMeasureSpec));
|
||||||
int height=Math.round(width*(tiledLayout.height/(float)PhotoLayoutHelper.MAX_WIDTH));
|
int height=Math.round(width*(tiledLayout.height/(float)PhotoLayoutHelper.MAX_WIDTH));
|
||||||
|
|
||||||
int offset=0;
|
int offset=0;
|
||||||
@@ -74,10 +74,9 @@ public class MediaGridLayout extends ViewGroup{
|
|||||||
if(tiledLayout==null)
|
if(tiledLayout==null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int maxWidth=V.dp(MAX_WIDTH);
|
|
||||||
int xOffset=0;
|
int xOffset=0;
|
||||||
if(r-l>maxWidth){
|
if(r-l>UiUtils.MAX_WIDTH){
|
||||||
xOffset=(r-l)/2-maxWidth/2;
|
xOffset=(r-l)/2-UiUtils.MAX_WIDTH/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0;i<getChildCount();i++){
|
for(int i=0;i<getChildCount();i++){
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -8,52 +8,53 @@ import java.time.Instant;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class StatusFilterPredicate implements Predicate<Status>{
|
public class StatusFilterPredicate implements Predicate<Status>{
|
||||||
private final List<Filter> filters;
|
private final List<Filter> filters;
|
||||||
|
private final Filter.FilterContext context;
|
||||||
|
private final Filter.FilterAction action;
|
||||||
|
|
||||||
public StatusFilterPredicate(List<Filter> filters){
|
public StatusFilterPredicate(List<Filter> filters, Filter.FilterContext context){
|
||||||
this.filters=filters;
|
this.filters=filters;
|
||||||
|
this.context = context;
|
||||||
|
this.action = Filter.FilterAction.HIDE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context null makes the predicate pass automatically
|
||||||
|
*/
|
||||||
public StatusFilterPredicate(String accountID, Filter.FilterContext context){
|
public StatusFilterPredicate(String accountID, Filter.FilterContext context){
|
||||||
|
this(accountID, context, Filter.FilterAction.HIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param context null makes the predicate pass automatically
|
||||||
|
* @param action defines what the predicate should check:
|
||||||
|
* should not be hidden or should not display with warning
|
||||||
|
*/
|
||||||
|
public StatusFilterPredicate(String accountID, Filter.FilterContext context, Filter.FilterAction action){
|
||||||
filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList());
|
filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(context)).collect(Collectors.toList());
|
||||||
|
this.context = context;
|
||||||
|
this.action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Status status){
|
public boolean test(Status status){
|
||||||
if(status.filtered!=null){
|
if (context == null) return true;
|
||||||
if (status.filtered.isEmpty()){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
boolean matches=status.filtered.stream()
|
|
||||||
.map(filterResult->filterResult.filter)
|
|
||||||
.filter(filter->filter.expiresAt==null||filter.expiresAt.isAfter(Instant.now()))
|
|
||||||
.anyMatch(filter->filter.filterAction==Filter.FilterAction.HIDE);
|
|
||||||
return !matches;
|
|
||||||
}
|
|
||||||
for(Filter filter:filters){
|
|
||||||
if(filter.matches(status))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean testWithWarning(Status status) {
|
Stream<Filter> stream = status.filtered != null
|
||||||
if(status.filtered!=null){
|
// use server-provided per-status info (status.filtered) if available
|
||||||
if (status.filtered.isEmpty()){
|
? status.filtered.stream().map(f -> f.filter)
|
||||||
return true;
|
// or fall back to cached filters
|
||||||
}
|
: filters.stream().filter(filter -> filter.matches(status));
|
||||||
boolean matches=status.filtered.stream()
|
|
||||||
.map(filterResult->filterResult.filter)
|
return stream
|
||||||
.filter(filter->filter.expiresAt==null||filter.expiresAt.isAfter(Instant.now()))
|
// discard expired filters
|
||||||
.anyMatch(filter->filter.filterAction==Filter.FilterAction.WARN);
|
.filter(filter -> filter.expiresAt == null || filter.expiresAt.isAfter(Instant.now()))
|
||||||
return !matches;
|
// only apply filters for given context
|
||||||
}
|
.filter(filter -> filter.context.contains(context))
|
||||||
for(Filter filter:filters){
|
// treating filterAction = null (from filters list) as FilterAction.HIDE
|
||||||
if(filter.matches(status))
|
.noneMatch(filter -> filter.filterAction == null ? action == Filter.FilterAction.HIDE : filter.filterAction == action);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4
mastodon/src/main/res/color/m3_on_surface_overlay.xml
Normal file
4
mastodon/src/main/res/color/m3_on_surface_overlay.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="?colorM3OnSurface" android:alpha="0.12"/>
|
||||||
|
</selector>
|
||||||
@@ -2,8 +2,14 @@
|
|||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item>
|
<item>
|
||||||
<shape>
|
<shape>
|
||||||
<solid android:color="?colorWindowBackground"/>
|
<solid android:color="?colorM3Surface"/>
|
||||||
<corners android:topLeftRadius="12dp" android:topRightRadius="12dp"/>
|
<corners android:topLeftRadius="28dp" android:topRightRadius="28dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:tint="?colorM3Primary">
|
||||||
|
<solid android:color="#0D000000"/>
|
||||||
|
<corners android:topLeftRadius="28dp" android:topRightRadius="28dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
</layer-list>
|
</layer-list>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:gravity="center" android:width="36dp" android:height="4dp">
|
<item android:gravity="center" android:width="32dp" android:height="4dp">
|
||||||
<shape>
|
<shape android:tint="?colorM3Outline">
|
||||||
<solid android:color="?android:textColorSecondary"/>
|
<solid android:color="#66000000"/>
|
||||||
<corners android:radius="2dp"/>
|
<corners android:radius="2dp"/>
|
||||||
</shape>
|
</shape>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
25
mastodon/src/main/res/drawable/bg_button_m3_outlined.xml
Normal file
25
mastodon/src/main/res/drawable/bg_button_m3_outlined.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple android:color="@color/m3_primary_overlay" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<selector>
|
||||||
|
<item android:state_enabled="true">
|
||||||
|
<shape>
|
||||||
|
<stroke android:color="?colorM3Outline" android:width="1dp"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<stroke android:color="@color/m3_on_surface_overlay" android:width="1dp"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
</item>
|
||||||
|
<item android:id="@android:id/mask">
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#000"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple android:color="#1effffff" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<selector>
|
||||||
|
<item android:state_enabled="true">
|
||||||
|
<shape>
|
||||||
|
<stroke android:color="?colorM3Outline" android:width="1dp"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<stroke android:color="@color/m3_on_surface_overlay" android:width="1dp"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
|
</item>
|
||||||
|
<item android:id="@android:id/mask">
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#000"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ripple android:color="#1effffff" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@android:id/mask">
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#000"/>
|
||||||
|
<corners android:radius="20dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||||
|
<path android:pathData="M20.063 8.445c1.256 1.258 1.255 3.295-0.002 4.551l-7.114 7.102c-0.271 0.272-0.608 0.469-0.978 0.573l-4.613 1.303c-0.57 0.162-1.094-0.373-0.92-0.94l1.387-4.543c0.107-0.354 0.3-0.675 0.562-0.936l7.124-7.112c1.258-1.256 3.297-1.255 4.554 0.002zM8.15 2.37L8.2 2.475l3.253 8.249-1.157 1.155L9.556 10H5.443l-0.995 2.52c-0.14 0.354-0.518 0.542-0.876 0.454l-0.098-0.031c-0.353-0.14-0.54-0.518-0.452-0.876l0.03-0.098 3.754-9.495C7.042 1.88 7.85 1.844 8.151 2.37zM7.503 4.792L6.036 8.5h2.928L7.503 4.792z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
||||||
|
<path android:pathData="M20.063 8.445c1.256 1.258 1.255 3.295-0.002 4.551l-7.123 7.112c-0.263 0.262-0.587 0.455-0.943 0.562l-4.293 1.29c-0.529 0.159-1.086-0.141-1.245-0.67-0.058-0.194-0.056-0.402 0.006-0.594l1.361-4.228c0.11-0.34 0.3-0.65 0.552-0.903l7.133-7.121c1.258-1.256 3.297-1.255 4.554 0.002zm-3.494 1.06l-7.133 7.12c-0.084 0.085-0.147 0.188-0.184 0.301l-1.07 3.323 3.382-1.015c0.119-0.036 0.227-0.1 0.314-0.188L19 11.936c0.672-0.671 0.672-1.76 0.002-2.43-0.672-0.672-1.76-0.673-2.433-0.002zM8.15 2.37L8.2 2.475l3.253 8.249-1.157 1.155L9.556 10H5.443l-0.995 2.52c-0.14 0.354-0.518 0.542-0.876 0.454l-0.098-0.031c-0.353-0.14-0.54-0.518-0.452-0.876l0.03-0.098 3.754-9.495C7.042 1.88 7.85 1.844 8.151 2.37zM7.503 4.792L6.036 8.5h2.928L7.503 4.792z" android:fillColor="@color/fluent_default_icon_tint"/>
|
||||||
|
</vector>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--~ Copyright (c) 2023. ~ Microsoft Corporation. All rights reserved.-->
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:drawable="@drawable/ic_fluent_text_edit_style_24_filled" android:state_activated="true"/>
|
||||||
|
<item android:drawable="@drawable/ic_fluent_text_edit_style_24_filled" android:state_checked="true"/>
|
||||||
|
<item android:drawable="@drawable/ic_fluent_text_edit_style_24_filled" android:state_selected="true"/>
|
||||||
|
<item android:drawable="@drawable/ic_fluent_text_edit_style_24_regular"/>
|
||||||
|
</selector>
|
||||||
27
mastodon/src/main/res/drawable/splash_logo.xml
Normal file
27
mastodon/src/main/res/drawable/splash_logo.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="134dp"
|
||||||
|
android:height="34dp"
|
||||||
|
android:viewportWidth="313"
|
||||||
|
android:viewportHeight="81">
|
||||||
|
<path
|
||||||
|
android:pathData="M72.95,18.45C71.82,9.95 64.5,3.24 55.85,1.95C54.38,1.73 48.85,0.93 36.02,0.93H35.92C23.09,0.93 20.34,1.73 18.87,1.95C10.44,3.22 2.76,9.23 0.88,17.84C-0,22.08 -0.1,26.78 0.07,31.09C0.31,37.27 0.36,43.43 0.91,49.6C1.29,53.69 1.95,57.74 2.9,61.73C4.68,69.11 11.86,75.25 18.9,77.75C26.43,80.35 34.53,80.79 42.29,79C43.14,78.79 43.98,78.56 44.82,78.29C46.71,77.68 48.92,77 50.55,75.81C50.57,75.8 50.59,75.77 50.6,75.75C50.61,75.72 50.62,75.7 50.62,75.66V69.7C50.62,69.7 50.62,69.65 50.6,69.62C50.6,69.6 50.57,69.58 50.55,69.56C50.53,69.55 50.5,69.54 50.48,69.53C50.45,69.53 50.43,69.53 50.41,69.53C45.43,70.73 40.33,71.34 35.23,71.33C26.43,71.33 24.06,67.09 23.39,65.34C22.85,63.82 22.5,62.22 22.36,60.61C22.36,60.59 22.36,60.57 22.37,60.54C22.37,60.52 22.39,60.49 22.42,60.48C22.44,60.47 22.46,60.46 22.49,60.44H22.57C27.46,61.64 32.48,62.25 37.51,62.25C38.72,62.25 39.92,62.25 41.14,62.21C46.19,62.06 51.52,61.81 56.51,60.82C56.63,60.8 56.76,60.77 56.87,60.75C64.72,59.21 72.19,54.42 72.95,42.27C72.97,41.79 73.04,37.25 73.04,36.76C73.04,35.07 73.58,24.79 72.96,18.48L72.95,18.45Z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:startX="36.62"
|
||||||
|
android:startY="0.93"
|
||||||
|
android:endX="36.62"
|
||||||
|
android:endY="80.07"
|
||||||
|
android:type="linear">
|
||||||
|
<item android:offset="0" android:color="#FF6364FF"/>
|
||||||
|
<item android:offset="1" android:color="#FF563ACC"/>
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:pathData="M14.81,23.2C14.81,20.72 16.77,18.72 19.2,18.72C21.62,18.72 23.58,20.73 23.58,23.2C23.58,25.67 21.62,27.68 19.2,27.68C16.77,27.68 14.81,25.67 14.81,23.2Z"
|
||||||
|
android:fillColor="#fff"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M80.02,27.06V47.66H72.03V27.67C72.03,23.45 70.3,21.32 66.83,21.32C63,21.32 61.07,23.87 61.07,28.87V39.82H53.14V28.87C53.14,23.84 51.24,21.32 47.38,21.32C43.92,21.32 42.18,23.45 42.18,27.67V47.65H34.21V27.06C34.21,22.86 35.25,19.51 37.35,17.03C39.53,14.54 42.37,13.29 45.89,13.29C49.97,13.29 53.07,14.9 55.11,18.11L57.11,21.52L59.1,18.11C61.14,14.91 64.23,13.29 68.32,13.29C71.84,13.29 74.69,14.55 76.86,17.03C78.96,19.51 80.01,22.83 80.01,27.06H80.02ZM107.49,37.3C109.15,35.51 109.93,33.29 109.93,30.59C109.93,27.89 109.14,25.65 107.49,23.94C105.91,22.15 103.89,21.3 101.45,21.3C99.02,21.3 97.01,22.15 95.41,23.94C93.83,25.65 93.04,27.89 93.04,30.59C93.04,33.29 93.83,35.53 95.41,37.3C97,39 99.02,39.87 101.45,39.87C103.89,39.87 105.9,39.02 107.49,37.3ZM109.93,14.12H117.8V47.06H109.93V43.18C107.55,46.41 104.26,48 99.99,48C95.71,48 92.42,46.36 89.5,43C86.64,39.64 85.18,35.48 85.18,30.61C85.18,25.74 86.65,21.65 89.5,18.29C92.43,14.93 95.92,13.23 99.99,13.23C104.06,13.23 107.55,14.81 109.93,18.02V14.14V14.12ZM144.26,29.97C146.58,31.76 147.73,34.25 147.67,37.41C147.67,40.77 146.52,43.41 144.14,45.24C141.76,47.03 138.89,47.94 135.41,47.94C129.13,47.94 124.87,45.3 122.61,40.11L129.43,35.96C130.34,38.78 132.35,40.25 135.41,40.25C138.22,40.25 139.62,39.33 139.62,37.42C139.62,36.03 137.79,34.78 134.07,33.8C132.66,33.41 131.5,33.01 130.6,32.68C129.31,32.16 128.22,31.56 127.31,30.83C125.05,29.04 123.9,26.68 123.9,23.65C123.9,20.42 124.99,17.85 127.19,16C129.45,14.09 132.19,13.18 135.48,13.18C140.73,13.18 144.56,15.48 147.07,20.16L140.37,24.1C139.4,21.86 137.74,20.74 135.48,20.74C133.11,20.74 131.95,21.65 131.95,23.44C131.95,24.83 133.78,26.08 137.5,27.06C140.37,27.72 142.63,28.7 144.26,29.97H144.27H144.26ZM169.26,22.27H162.37V35.98C162.37,37.63 162.98,38.63 164.15,39.08C165,39.4 166.71,39.47 169.27,39.34V47.05C163.98,47.71 160.14,47.17 157.88,45.41C155.62,43.7 154.53,40.53 154.53,36V22.27H149.23V14.1H154.53V7.46L162.39,4.89V14.12H169.29V22.29H169.27L169.26,22.27ZM194.34,37.1C195.92,35.4 196.71,33.22 196.71,30.58C196.71,27.94 195.92,25.78 194.34,24.05C192.74,22.35 190.79,21.48 188.42,21.48C186.04,21.48 184.09,22.33 182.49,24.05C180.97,25.84 180.18,28 180.18,30.58C180.18,33.16 180.97,35.31 182.49,37.1C184.08,38.81 186.04,39.67 188.42,39.67C190.79,39.67 192.74,38.82 194.34,37.1ZM176.96,42.96C173.85,39.6 172.32,35.52 172.32,30.58C172.32,25.63 173.85,21.62 176.96,18.26C180.07,14.9 183.91,13.19 188.42,13.19C192.92,13.19 196.77,14.9 199.87,18.26C202.97,21.62 204.57,25.77 204.57,30.58C204.57,35.39 202.97,39.6 199.87,42.96C196.76,46.32 192.98,47.96 188.42,47.96C183.85,47.96 180.06,46.32 176.96,42.96ZM230.86,37.29C232.45,35.5 233.24,33.28 233.24,30.58C233.24,27.87 232.45,25.63 230.86,23.93C229.28,22.14 227.26,21.29 224.82,21.29C222.39,21.29 220.37,22.14 218.73,23.93C217.14,25.63 216.35,27.87 216.35,30.58C216.35,33.28 217.14,35.52 218.73,37.29C220.38,38.99 222.45,39.86 224.82,39.86C227.2,39.86 229.27,39 230.86,37.29ZM233.24,0.92H241.11V47.05H233.24V43.17C230.93,46.39 227.63,47.99 223.36,47.99C219.09,47.99 215.75,46.35 212.8,42.98C209.93,39.62 208.48,35.47 208.48,30.6C208.48,25.73 209.95,21.64 212.8,18.28C215.72,14.92 219.26,13.22 223.36,13.22C227.45,13.22 230.93,14.8 233.24,18.01V0.93V0.92ZM268.74,37.07C270.32,35.36 271.12,33.18 271.12,30.54C271.12,27.9 270.32,25.74 268.74,24.01C267.15,22.31 265.21,21.45 262.82,21.45C260.43,21.45 258.5,22.3 256.9,24.01C255.37,25.8 254.58,27.96 254.58,30.54C254.58,33.12 255.37,35.28 256.9,37.07C258.48,38.77 260.44,39.64 262.82,39.64C265.2,39.64 267.14,38.78 268.74,37.07ZM251.36,42.92C248.26,39.56 246.73,35.48 246.73,30.54C246.73,25.6 248.25,21.58 251.36,18.22C254.47,14.86 258.32,13.15 262.82,13.15C267.32,13.15 271.18,14.86 274.27,18.22C277.38,21.58 278.97,25.73 278.97,30.54C278.97,35.35 277.38,39.56 274.27,42.92C271.16,46.28 267.38,47.93 262.82,47.93C258.26,47.93 254.46,46.28 251.36,42.92ZM313,26.78V47.01H305.14V27.84C305.14,25.66 304.59,24.01 303.48,22.77C302.45,21.65 300.98,21.07 299.09,21.07C294.65,21.07 292.39,23.77 292.39,29.24V47.03H284.53V14.1H292.39V17.81C294.28,14.71 297.28,13.19 301.47,13.19C304.82,13.19 307.57,14.37 309.71,16.81C311.91,19.24 313,22.54 313,26.82"
|
||||||
|
android:fillColor="#fff"/>
|
||||||
|
</vector>
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
android:paddingHorizontal="5dp"
|
android:paddingHorizontal="5dp"
|
||||||
android:paddingVertical="1dp"
|
android:paddingVertical="2dp"
|
||||||
android:background="@drawable/bg_image_alt_overlay"
|
android:background="@drawable/bg_image_alt_overlay"
|
||||||
android:text="@string/sk_alt_button"/>
|
android:text="@string/sk_alt_button"/>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="13dp"
|
|
||||||
android:paddingEnd="4dp"
|
android:paddingEnd="4dp"
|
||||||
android:paddingStart="16dp">
|
android:paddingStart="16dp">
|
||||||
|
|
||||||
@@ -11,6 +10,7 @@
|
|||||||
android:id="@+id/more"
|
android:id="@+id/more"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
android:id="@+id/delete_notification"
|
android:id="@+id/delete_notification"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
android:layout_toStartOf="@id/more"
|
android:layout_toStartOf="@id/more"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
android:id="@+id/visibility"
|
android:id="@+id/visibility"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
android:layout_toStartOf="@id/delete_notification"
|
android:layout_toStartOf="@id/delete_notification"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
@@ -46,6 +48,7 @@
|
|||||||
android:id="@+id/collapse_btn"
|
android:id="@+id/collapse_btn"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
android:layout_toStartOf="@id/visibility"
|
android:layout_toStartOf="@id/visibility"
|
||||||
android:background="?android:actionBarItemBackground"
|
android:background="?android:actionBarItemBackground"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
@@ -70,6 +73,7 @@
|
|||||||
android:id="@+id/unread_indicator"
|
android:id="@+id/unread_indicator"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="13dp"
|
||||||
android:layout_toStartOf="@id/collapse_btn"
|
android:layout_toStartOf="@id/collapse_btn"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:tint="?android:colorAccent"
|
android:tint="?android:colorAccent"
|
||||||
@@ -83,18 +87,16 @@
|
|||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:layout_marginTop="3dp" />
|
android:layout_marginTop="16dp" />
|
||||||
|
|
||||||
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
|
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
|
||||||
android:id="@+id/name_wrap"
|
android:id="@+id/name_wrap"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:paddingTop="4sp"
|
|
||||||
android:layout_toStartOf="@id/unread_indicator"
|
android:layout_toStartOf="@id/unread_indicator"
|
||||||
android:layout_toEndOf="@id/avatar"
|
android:layout_toEndOf="@id/avatar"
|
||||||
android:minHeight="24sp">
|
android:layout_above="@+id/username_wrap">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/name"
|
android:id="@+id/name"
|
||||||
@@ -121,14 +123,15 @@
|
|||||||
</org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout>
|
</org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout>
|
||||||
|
|
||||||
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
|
<org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout
|
||||||
|
android:id="@id/username_wrap"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/name_wrap"
|
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_toStartOf="@id/unread_indicator"
|
android:layout_toStartOf="@id/unread_indicator"
|
||||||
android:layout_toEndOf="@id/avatar"
|
android:layout_toEndOf="@id/avatar"
|
||||||
|
android:layout_alignBottom="@id/avatar"
|
||||||
android:layoutDirection="locale"
|
android:layoutDirection="locale"
|
||||||
android:minHeight="20sp"
|
android:paddingBottom="3sp"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
android:layout_height="250dp"
|
android:layout_height="250dp"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:foreground="?android:selectableItemBackground"
|
android:foreground="?android:selectableItemBackground"
|
||||||
android:maxWidth="400dp">
|
android:maxWidth="@dimen/layout_max_width">
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/photo"
|
android:id="@+id/photo"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -73,7 +73,6 @@
|
|||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="16dp"
|
|
||||||
android:paddingRight="16dp"
|
android:paddingRight="16dp"
|
||||||
android:paddingLeft="16dp">
|
android:paddingLeft="16dp">
|
||||||
|
|
||||||
@@ -81,6 +80,7 @@
|
|||||||
android:id="@+id/self_avatar"
|
android:id="@+id/self_avatar"
|
||||||
android:layout_width="46sp"
|
android:layout_width="46sp"
|
||||||
android:layout_height="46sp"
|
android:layout_height="46sp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:layout_marginEnd="12dp" />
|
android:layout_marginEnd="12dp" />
|
||||||
@@ -90,8 +90,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_toEndOf="@id/self_avatar"
|
android:layout_toEndOf="@id/self_avatar"
|
||||||
android:paddingTop="4sp"
|
android:layout_above="@+id/self_username"
|
||||||
android:minHeight="24sp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/m3_title_medium"
|
android:textAppearance="@style/m3_title_medium"
|
||||||
@@ -103,7 +102,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8sp"
|
android:layout_marginStart="8sp"
|
||||||
android:layout_toEndOf="@id/self_name"
|
android:layout_toEndOf="@id/self_name"
|
||||||
android:paddingTop="4sp"
|
android:layout_above="@id/self_username"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
@@ -112,15 +111,15 @@
|
|||||||
tools:text="@string/sk_local_only" />
|
tools:text="@string/sk_local_only" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/self_username"
|
android:id="@id/self_username"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/self_name"
|
|
||||||
android:layout_toEndOf="@id/self_avatar"
|
android:layout_toEndOf="@id/self_avatar"
|
||||||
android:minHeight="20sp"
|
android:layout_alignBottom="@id/self_avatar"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textAppearance="@style/m3_title_small"
|
android:textAppearance="@style/m3_title_small"
|
||||||
|
android:paddingBottom="3sp"
|
||||||
tools:text="\@Gargron" />
|
tools:text="\@Gargron" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
@@ -417,6 +416,19 @@
|
|||||||
android:tooltipText="@string/post_visibility"
|
android:tooltipText="@string/post_visibility"
|
||||||
android:src="@drawable/ic_fluent_earth_24_regular"/>
|
android:src="@drawable/ic_fluent_earth_24_regular"/>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btn_content_type"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginEnd="12dp"
|
||||||
|
android:background="?android:attr/actionBarItemBackground"
|
||||||
|
android:padding="0px"
|
||||||
|
android:tint="@color/compose_button"
|
||||||
|
android:tintMode="src_in"
|
||||||
|
android:contentDescription="@string/sk_content_type"
|
||||||
|
android:tooltipText="@string/sk_content_type"
|
||||||
|
android:src="@drawable/ic_fluent_text_edit_style_24_selector"/>
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:layout_width="0px"
|
android:layout_width="0px"
|
||||||
android:layout_height="1px"
|
android:layout_height="1px"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<org.joinmastodon.android.ui.views.MaxWidthFrameLayout
|
<org.joinmastodon.android.ui.views.MaxWidthFrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:maxWidth="400dp">
|
android:maxWidth="@dimen/layout_max_width">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/photo"
|
android:id="@+id/photo"
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false"
|
||||||
|
android:theme="@style/Theme.Mastodon.Dark.SplashFragment">
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/blue_fill"
|
android:id="@+id/blue_fill"
|
||||||
@@ -26,7 +27,8 @@
|
|||||||
android:id="@+id/art_clouds"
|
android:id="@+id/art_clouds"
|
||||||
android:layout_width="414dp"
|
android:layout_width="414dp"
|
||||||
android:layout_height="541dp"
|
android:layout_height="541dp"
|
||||||
android:layout_marginTop="91dp"
|
android:layout_marginTop="37dp"
|
||||||
|
android:layout_marginLeft="-27dp"
|
||||||
android:layout_gravity="top|left"
|
android:layout_gravity="top|left"
|
||||||
android:alpha="0.3"
|
android:alpha="0.3"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
@@ -36,8 +38,8 @@
|
|||||||
android:id="@+id/art_plane_elephant"
|
android:id="@+id/art_plane_elephant"
|
||||||
android:layout_width="245.64dp"
|
android:layout_width="245.64dp"
|
||||||
android:layout_height="72.65dp"
|
android:layout_height="72.65dp"
|
||||||
android:layout_marginLeft="-101.55dp"
|
android:layout_marginLeft="-50.775dp"
|
||||||
android:layout_marginTop="238.12dp"
|
android:layout_marginTop="184.12dp"
|
||||||
android:layout_gravity="left|top"
|
android:layout_gravity="left|top"
|
||||||
android:alpha="0.3"
|
android:alpha="0.3"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
@@ -48,8 +50,8 @@
|
|||||||
android:layout_width="150.84dp"
|
android:layout_width="150.84dp"
|
||||||
android:layout_height="176.44dp"
|
android:layout_height="176.44dp"
|
||||||
android:layout_gravity="top|left"
|
android:layout_gravity="top|left"
|
||||||
android:layout_marginLeft="322dp"
|
android:layout_marginLeft="278dp"
|
||||||
android:layout_marginTop="310dp"
|
android:layout_marginTop="244dp"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:src="@drawable/splash_art_layer1"/>
|
android:src="@drawable/splash_art_layer1"/>
|
||||||
|
|
||||||
@@ -58,7 +60,8 @@
|
|||||||
android:layout_width="197.2dp"
|
android:layout_width="197.2dp"
|
||||||
android:layout_height="153.61dp"
|
android:layout_height="153.61dp"
|
||||||
android:layout_gravity="top|left"
|
android:layout_gravity="top|left"
|
||||||
android:layout_marginTop="294dp"
|
android:layout_marginTop="252dp"
|
||||||
|
android:layout_marginLeft="-44dp"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:src="@drawable/splash_art_layer2"/>
|
android:src="@drawable/splash_art_layer2"/>
|
||||||
|
|
||||||
@@ -67,7 +70,8 @@
|
|||||||
android:layout_width="400dp"
|
android:layout_width="400dp"
|
||||||
android:layout_height="346dp"
|
android:layout_height="346dp"
|
||||||
android:layout_gravity="top|left"
|
android:layout_gravity="top|left"
|
||||||
android:layout_marginTop="294dp"
|
android:layout_marginTop="240dp"
|
||||||
|
android:layout_marginLeft="-20dp"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:src="@drawable/splash_art_layer3"/>
|
android:src="@drawable/splash_art_layer3"/>
|
||||||
|
|
||||||
@@ -86,60 +90,108 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="300dp"
|
||||||
|
android:layout_height="78dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:src="@drawable/splash_logo"/>
|
||||||
|
|
||||||
<androidx.viewpager2.widget.ViewPager2
|
<Space
|
||||||
android:id="@+id/pager"
|
android:layout_width="1px"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="0px"
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/pager_dots"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="8dp"
|
|
||||||
android:layout_height="8dp"
|
|
||||||
android:background="@drawable/white_circle"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="8dp"
|
|
||||||
android:layout_height="8dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:alpha="0.3"
|
|
||||||
android:background="@drawable/white_circle"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="8dp"
|
|
||||||
android:layout_height="8dp"
|
|
||||||
android:alpha="0.3"
|
|
||||||
android:background="@drawable/white_circle"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btn_log_in"
|
android:id="@+id/btn_join_default_server"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
style="@style/Widget.Mastodon.M3.Button.Text"
|
style="@style/Widget.Mastodon.M3.Button.Filled"
|
||||||
android:textColor="#fff"
|
tools:text="@string/join_default_server"/>
|
||||||
android:text="@string/already_have_account"/>
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btn_get_started"
|
android:id="@+id/btn_get_started"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="16dp"
|
android:layout_marginLeft="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginTop="8dp"
|
||||||
style="@style/Widget.Mastodon.M3.Button.Filled"
|
android:textColor="#FFF"
|
||||||
android:text="@string/get_started"/>
|
style="@style/Widget.Mastodon.M3.Button.Outlined"
|
||||||
|
android:background="@drawable/bg_button_m3_outlined_white"
|
||||||
|
android:text="@string/pick_server"/>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="#B2FFFFFF"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:textAllCaps="true"
|
||||||
|
android:textAppearance="@style/m3_label_large"
|
||||||
|
android:textColor="#B2FFFFFF"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:text="@string/signup_or_login"/>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:background="#B2FFFFFF"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_learn_more"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textColor="#FFF"
|
||||||
|
style="@style/Widget.Mastodon.M3.Button.Text"
|
||||||
|
android:background="@drawable/bg_button_m3_text_white"
|
||||||
|
android:text="@string/learn_more"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_log_in"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:textColor="#FFF"
|
||||||
|
style="@style/Widget.Mastodon.M3.Button.Text"
|
||||||
|
android:background="@drawable/bg_button_m3_text_white"
|
||||||
|
android:text="@string/log_in"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</org.joinmastodon.android.ui.views.SizeListenerFrameLayout>
|
</org.joinmastodon.android.ui.views.SizeListenerFrameLayout>
|
||||||
50
mastodon/src/main/res/layout/intro_bottom_sheet.xml
Normal file
50
mastodon/src/main/res/layout/intro_bottom_sheet.xml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/bg_bottom_sheet"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="4dp"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:background="@drawable/bg_bottom_sheet_handle"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/m3_headline_medium"
|
||||||
|
android:textColor="?colorM3OnSurface"
|
||||||
|
android:text="@string/welcome_to_mastodon"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:textColor="?colorM3OnSurface"
|
||||||
|
android:text="@string/welcome_paragraph1"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:textAppearance="@style/m3_headline_medium"
|
||||||
|
android:textColor="?colorM3OnSurface"
|
||||||
|
android:text="@string/what_are_servers"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:textColor="?colorM3OnSurface"
|
||||||
|
android:text="@string/welcome_paragraph2"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?colorBackgroundLight"
|
android:background="?colorBackgroundLight"
|
||||||
android:elevation="2dp"
|
android:elevation="2dp"
|
||||||
android:paddingBottom="16dp">
|
android:paddingBottom="0dp">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/cover"
|
android:id="@+id/cover"
|
||||||
@@ -56,9 +56,9 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/username"
|
android:id="@+id/username"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="20dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignLeft="@id/name"
|
android:layout_alignStart="@id/name"
|
||||||
android:layout_alignRight="@id/name"
|
android:layout_alignEnd="@id/name"
|
||||||
android:layout_below="@id/name"
|
android:layout_below="@id/name"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
@@ -81,92 +81,110 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/bio"
|
android:layout_below="@id/bio"
|
||||||
android:paddingRight="8dp"
|
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<LinearLayout
|
<org.joinmastodon.android.ui.views.AutoOrientationLinearLayout
|
||||||
android:id="@+id/posts_btn"
|
android:layout_width="0dp"
|
||||||
android:layout_width="wrap_content"
|
android:layout_weight="1"
|
||||||
android:layout_height="48dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_gravity="bottom"
|
||||||
android:gravity="center_horizontal"
|
android:paddingTop="4dp"
|
||||||
android:orientation="vertical">
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="44dp">
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/posts_count"
|
android:id="@+id/posts_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/m3_title_large"
|
android:layout_marginTop="2dp"
|
||||||
tools:text="123" />
|
android:layout_marginEnd="8dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/posts_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/m3_title_medium"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
tools:text="123" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/posts_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4sp"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
tools:text="posts" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<LinearLayout
|
||||||
android:id="@+id/posts_label"
|
android:id="@+id/following_btn"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/m3_title_small"
|
android:layout_marginTop="2dp"
|
||||||
tools:text="following" />
|
android:layout_marginEnd="8dp"
|
||||||
</LinearLayout>
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/following_count"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/m3_title_medium"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="end"
|
||||||
|
tools:text="123"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/following_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="4sp"
|
||||||
|
android:textAppearance="@style/m3_body_large"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:ellipsize="middle"
|
||||||
|
tools:text="following"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/followers_btn"
|
android:id="@+id/followers_btn"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="48dp"
|
|
||||||
android:layout_marginTop="16dp"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:gravity="center_horizontal">
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/followers_count"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/m3_title_large"
|
android:layout_marginTop="2dp"
|
||||||
tools:text="123"/>
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/followers_label"
|
android:id="@+id/followers_count"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/m3_title_small"
|
android:textAppearance="@style/m3_title_medium"
|
||||||
tools:text="following"/>
|
android:singleLine="true"
|
||||||
</LinearLayout>
|
android:ellipsize="end"
|
||||||
|
tools:text="123"/>
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:id="@+id/following_btn"
|
android:id="@+id/followers_label"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="48dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginStart="4sp"
|
||||||
android:layout_marginStart="12dp"
|
android:textAppearance="@style/m3_body_large"
|
||||||
android:orientation="vertical"
|
android:singleLine="true"
|
||||||
android:gravity="center_horizontal">
|
android:ellipsize="middle"
|
||||||
<TextView
|
tools:text="followers"/>
|
||||||
android:id="@+id/following_count"
|
</LinearLayout>
|
||||||
android:layout_width="wrap_content"
|
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@style/m3_title_large"
|
|
||||||
tools:text="123"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/following_label"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@style/m3_title_small"
|
|
||||||
tools:text="following"/>
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<Space
|
|
||||||
android:layout_width="0px"
|
|
||||||
android:layout_height="1px"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/reject_btn_wrap"
|
android:id="@+id/reject_btn_wrap"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_gravity="bottom"
|
||||||
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="4dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:paddingHorizontal="4dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingVertical="8dp"
|
android:paddingBottom="16dp"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||||
@@ -194,10 +212,12 @@
|
|||||||
android:id="@+id/accept_btn_wrap"
|
android:id="@+id/accept_btn_wrap"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_gravity="bottom"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:paddingHorizontal="4dp"
|
android:paddingTop="8dp"
|
||||||
android:paddingVertical="8dp"
|
android:paddingBottom="16dp"
|
||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||||
@@ -224,8 +244,11 @@
|
|||||||
android:id="@+id/action_btn_wrap"
|
android:id="@+id/action_btn_wrap"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_gravity="bottom"
|
||||||
android:padding="8dp"
|
android:paddingStart="8dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingTop="8dp"
|
||||||
|
android:paddingBottom="16dp"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<org.joinmastodon.android.ui.views.ProgressBarButton
|
<org.joinmastodon.android.ui.views.ProgressBarButton
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="24dp"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="32dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:importantForAccessibility="no"
|
android:importantForAccessibility="no"
|
||||||
android:tint="?android:textColorPrimary"
|
android:tint="?android:textColorPrimary"
|
||||||
tools:src="@drawable/ic_fluent_color_24_regular"/>
|
tools:src="@drawable/ic_fluent_color_24_regular"/>
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:paddingVertical="8dp"
|
android:paddingVertical="8dp"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:includeFontPadding="false"
|
android:includeFontPadding="false"
|
||||||
android:paddingHorizontal="5dp"
|
android:paddingHorizontal="5dp"
|
||||||
android:paddingVertical="1dp"
|
android:paddingVertical="2dp"
|
||||||
android:text="@string/sk_alt_button"/>
|
android:text="@string/sk_alt_button"/>
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
|||||||
11
mastodon/src/main/res/menu/compose_content_type.xml
Normal file
11
mastodon/src/main/res/menu/compose_content_type.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<group android:id="@+id/content_type_group" android:checkableBehavior="single">
|
||||||
|
<item android:id="@+id/content_type_null" android:title="@string/sk_content_type_unspecified" />
|
||||||
|
<item android:id="@+id/content_type_plain" android:title="@string/sk_content_type_plain" />
|
||||||
|
<item android:id="@+id/content_type_markdown" android:title="@string/sk_content_type_markdown" />
|
||||||
|
<item android:id="@+id/content_type_html" android:title="@string/sk_content_type_html" />
|
||||||
|
<item android:id="@+id/content_type_bbcode" android:title="@string/sk_content_type_bbcode" />
|
||||||
|
<item android:id="@+id/content_type_misskey_markdown" android:title="@string/sk_content_type_mfm" />
|
||||||
|
</group>
|
||||||
|
</menu>
|
||||||
488
mastodon/src/main/res/values-ar-rDZ/strings.xml
Normal file
488
mastodon/src/main/res/values-ar-rDZ/strings.xml
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="get_started">الخطوات الأولى</string>
|
||||||
|
<string name="log_in">تسجيلُ الدخول</string>
|
||||||
|
<string name="next">التالي</string>
|
||||||
|
<string name="loading_instance">يَجري الحُصُول على معلومات المَثيل…</string>
|
||||||
|
<string name="error">خطأ</string>
|
||||||
|
<string name="not_a_mastodon_instance">%s لا يبدو كمثيل ماستدون.</string>
|
||||||
|
<string name="ok">حسنًا</string>
|
||||||
|
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
||||||
|
<string name="finishing_auth">يُنهي المصادقة…</string>
|
||||||
|
<string name="user_boosted">أعادَ %s تَدوينَها</string>
|
||||||
|
<string name="in_reply_to">ردًا على %s</string>
|
||||||
|
<string name="notifications">الإشعارات</string>
|
||||||
|
<string name="user_followed_you">بَدَأ بِمُتابَعَتِك</string>
|
||||||
|
<string name="user_sent_follow_request">أرسَلَ طَلَبًا لِمُتابَعَتِك</string>
|
||||||
|
<string name="user_favorited">فَضَّلَ مَنشُورَك</string>
|
||||||
|
<string name="notification_boosted">أعادَ تَدوينَ مَنشُورَك</string>
|
||||||
|
<string name="poll_ended">انتهى استطلاعُ الرأي</string>
|
||||||
|
<string name="time_seconds">%d ثا</string>
|
||||||
|
<string name="time_minutes">%d د</string>
|
||||||
|
<string name="time_hours">%d سا</string>
|
||||||
|
<string name="time_days">%d يوم</string>
|
||||||
|
<string name="share_toot_title">شارك</string>
|
||||||
|
<string name="settings">الإعدادات</string>
|
||||||
|
<string name="publish">انشر</string>
|
||||||
|
<string name="discard_draft">أتريد التخلص من المسودة؟</string>
|
||||||
|
<string name="discard">تخلص</string>
|
||||||
|
<string name="cancel">إلغاء</string>
|
||||||
|
<plurals name="followers">
|
||||||
|
<item quantity="zero">لا متابِعين</item>
|
||||||
|
<item quantity="one">متابِع</item>
|
||||||
|
<item quantity="two">متابِعان</item>
|
||||||
|
<item quantity="few">متابِعين</item>
|
||||||
|
<item quantity="many">متابِعًا</item>
|
||||||
|
<item quantity="other">متابِع</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="following">
|
||||||
|
<item quantity="zero">لا متابَعين</item>
|
||||||
|
<item quantity="one">متابَع</item>
|
||||||
|
<item quantity="two">متابَعان</item>
|
||||||
|
<item quantity="few">متابَعين</item>
|
||||||
|
<item quantity="many">متابَعًا</item>
|
||||||
|
<item quantity="other">متابَع</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="posts">
|
||||||
|
<item quantity="zero">لا منشورات</item>
|
||||||
|
<item quantity="one">منشور</item>
|
||||||
|
<item quantity="two">منشوران</item>
|
||||||
|
<item quantity="few">منشورات</item>
|
||||||
|
<item quantity="many">منشورًا</item>
|
||||||
|
<item quantity="other">منشور</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="posts">منشورات</string>
|
||||||
|
<string name="posts_and_replies">مَنشُوراتٌ وَرُدُود</string>
|
||||||
|
<string name="media">وسائط</string>
|
||||||
|
<string name="profile_about">حَول</string>
|
||||||
|
<string name="button_follow">تابِع</string>
|
||||||
|
<string name="button_following">يُتابِع</string>
|
||||||
|
<string name="edit_profile">حرّر الملف الشخصي</string>
|
||||||
|
<string name="mention_user">ذِكر @%s</string>
|
||||||
|
<string name="share_user">مُشارَكَةُ %s</string>
|
||||||
|
<string name="mute_user">كَتمُ %s</string>
|
||||||
|
<string name="unmute_user">إلغاء الكَتم عن @%s</string>
|
||||||
|
<string name="block_user">حَظرُ %s</string>
|
||||||
|
<string name="unblock_user">رفع الحَظر عن %s</string>
|
||||||
|
<string name="report_user">الإبلاغُ عَن %s</string>
|
||||||
|
<string name="block_domain">حَظرُ %s</string>
|
||||||
|
<string name="unblock_domain">رفع الحَظر عن %s</string>
|
||||||
|
<plurals name="x_posts">
|
||||||
|
<item quantity="zero">لا مَنشورات</item>
|
||||||
|
<item quantity="one">منشورٌ واحِد</item>
|
||||||
|
<item quantity="two">منشورانِ اثنان</item>
|
||||||
|
<item quantity="few">%,d منشورات</item>
|
||||||
|
<item quantity="many">%,d منشورًا</item>
|
||||||
|
<item quantity="other">%,d منشور</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="profile_joined">انضم في</string>
|
||||||
|
<string name="done">تمّ</string>
|
||||||
|
<string name="loading">يحمل…</string>
|
||||||
|
<string name="field_label">التسمية</string>
|
||||||
|
<string name="field_content">المحتوى</string>
|
||||||
|
<string name="saving">يحفظ…</string>
|
||||||
|
<string name="post_from_user">نُشر من %s</string>
|
||||||
|
<string name="poll_option_hint">الخيار %d</string>
|
||||||
|
<plurals name="x_minutes">
|
||||||
|
<item quantity="zero">أقل من دقيقة</item>
|
||||||
|
<item quantity="one">دقيقة واحدة</item>
|
||||||
|
<item quantity="two">دقيقتان</item>
|
||||||
|
<item quantity="few">%d دقائق</item>
|
||||||
|
<item quantity="many">%d دقيقة</item>
|
||||||
|
<item quantity="other">%d دقيقة</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_hours">
|
||||||
|
<item quantity="zero">أقل من ساعة</item>
|
||||||
|
<item quantity="one">ساعة واحدة</item>
|
||||||
|
<item quantity="two">ساعتان</item>
|
||||||
|
<item quantity="few">%d ساعات</item>
|
||||||
|
<item quantity="many">%d ساعة</item>
|
||||||
|
<item quantity="other">%d ساعة</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_days">
|
||||||
|
<item quantity="zero">أقل من يوم</item>
|
||||||
|
<item quantity="one">يومٌ واحِد</item>
|
||||||
|
<item quantity="two">يَومان</item>
|
||||||
|
<item quantity="few">%d أيام</item>
|
||||||
|
<item quantity="many">%d يومًا</item>
|
||||||
|
<item quantity="other">%d يوم</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="compose_poll_duration">المُدَّة: %s</string>
|
||||||
|
<plurals name="x_seconds_left">
|
||||||
|
<item quantity="zero">تتبقى لَحظة</item>
|
||||||
|
<item quantity="one">تتبقى ثانية واحِدة</item>
|
||||||
|
<item quantity="two">تتبقى ثانيتان</item>
|
||||||
|
<item quantity="few">تتبقى %d ثوان</item>
|
||||||
|
<item quantity="many">تتبقى %d ثانية</item>
|
||||||
|
<item quantity="other">تتبقى %d ثانية</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_minutes_left">
|
||||||
|
<item quantity="zero">تبقت أقل من دقيقة</item>
|
||||||
|
<item quantity="one">تبقت دقيقة</item>
|
||||||
|
<item quantity="two">تبقت دقيقتان</item>
|
||||||
|
<item quantity="few">تبقت %d دقائق</item>
|
||||||
|
<item quantity="many">تبقت %d دقيقة</item>
|
||||||
|
<item quantity="other">تبقت %d دقيقة</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_hours_left">
|
||||||
|
<item quantity="zero">تبقت أقل من ساعة</item>
|
||||||
|
<item quantity="one">تبقت ساعة واحدة</item>
|
||||||
|
<item quantity="two">تبقت ساعتان</item>
|
||||||
|
<item quantity="few">تبقت %d ساعات</item>
|
||||||
|
<item quantity="many">تبقت %d ساعة</item>
|
||||||
|
<item quantity="other">تبقت %d ساعة</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_days_left">
|
||||||
|
<item quantity="zero">تبقى أقل من يوم</item>
|
||||||
|
<item quantity="one">تبقى يوم واحد</item>
|
||||||
|
<item quantity="two">تبقى يومان</item>
|
||||||
|
<item quantity="few">تبقى %d أيام</item>
|
||||||
|
<item quantity="many">تبقى %d يومًا</item>
|
||||||
|
<item quantity="other">تبقى %d يوم</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_voters">
|
||||||
|
<item quantity="zero">لا يوجد مصوتون</item>
|
||||||
|
<item quantity="one">مصوت واحد</item>
|
||||||
|
<item quantity="two">مصوتان</item>
|
||||||
|
<item quantity="few">%,d مصوتين</item>
|
||||||
|
<item quantity="many">%,d مصوتًا</item>
|
||||||
|
<item quantity="other">%,d مصوت</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="poll_closed">انتهى</string>
|
||||||
|
<string name="confirm_mute_title">اكتم الحساب</string>
|
||||||
|
<string name="confirm_mute">أكّد كتم %s</string>
|
||||||
|
<string name="do_mute">اكتم</string>
|
||||||
|
<string name="confirm_unmute_title">ارفع الكتم عن الحساب</string>
|
||||||
|
<string name="confirm_unmute">أكِّد رفع الكتم عن %s</string>
|
||||||
|
<string name="do_unmute">ارفع الكتم</string>
|
||||||
|
<string name="confirm_block_title">احجب الحساب</string>
|
||||||
|
<string name="confirm_block_domain_title">احجب النطاق</string>
|
||||||
|
<string name="confirm_block">أكّد حجب %s</string>
|
||||||
|
<string name="do_block">احجب</string>
|
||||||
|
<string name="confirm_unblock_title">ارفع الحجب عن الحساب</string>
|
||||||
|
<string name="confirm_unblock_domain_title">ارفع الحجب عن النطاق</string>
|
||||||
|
<string name="confirm_unblock">أكّد رفع الحجب عن %s</string>
|
||||||
|
<string name="do_unblock">ارفع الحجب</string>
|
||||||
|
<string name="button_muted">مَكتوم</string>
|
||||||
|
<string name="button_blocked">محجوب</string>
|
||||||
|
<string name="action_vote">صَوّت</string>
|
||||||
|
<string name="tap_to_reveal">اُنقُر لِلكَشف</string>
|
||||||
|
<string name="delete">احذف</string>
|
||||||
|
<string name="confirm_delete_title">احذف المنشور</string>
|
||||||
|
<string name="confirm_delete">أمتأكد من حذف هذا المنشور؟</string>
|
||||||
|
<string name="deleting">يحذف…</string>
|
||||||
|
<string name="notification_channel_audio_player">تشغيل الصوت</string>
|
||||||
|
<string name="play">شغّل</string>
|
||||||
|
<string name="pause">ألبث</string>
|
||||||
|
<string name="log_out">خروج</string>
|
||||||
|
<string name="add_account">أضف حساباً</string>
|
||||||
|
<string name="search_hint">ابحث</string>
|
||||||
|
<string name="hashtags">وُسُوم</string>
|
||||||
|
<string name="news">الأخبار</string>
|
||||||
|
<string name="for_you">لأجلك</string>
|
||||||
|
<string name="all_notifications">الكل</string>
|
||||||
|
<string name="mentions">الذِكر</string>
|
||||||
|
<plurals name="x_people_talking">
|
||||||
|
<item quantity="zero">لا أحد يتحدث</item>
|
||||||
|
<item quantity="one">شخص واحد يتحدث</item>
|
||||||
|
<item quantity="two">شخصان يتحدثان</item>
|
||||||
|
<item quantity="few">%d أشخاص يتحدثون</item>
|
||||||
|
<item quantity="many">%d شخصًا يتحدثون</item>
|
||||||
|
<item quantity="other">%d شخص يتحدثون</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="discussed_x_times">
|
||||||
|
<item quantity="zero">لم يُناقش</item>
|
||||||
|
<item quantity="one">نوقش مرة واحدة</item>
|
||||||
|
<item quantity="two">نوقش مرتين</item>
|
||||||
|
<item quantity="few">نوقش %d مرات</item>
|
||||||
|
<item quantity="many">نوقش %d مرة</item>
|
||||||
|
<item quantity="other">نوقش %d مرة</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="report_title">بلّغ عن %s</string>
|
||||||
|
<string name="report_choose_reason">ما هي المشكلة في هذا المنشور؟</string>
|
||||||
|
<string name="report_choose_reason_account">ما هي المشكلة مع %s؟</string>
|
||||||
|
<string name="report_choose_reason_subtitle">اختر أفضل تطابق</string>
|
||||||
|
<string name="report_reason_personal">لا يعجبني</string>
|
||||||
|
<string name="report_reason_personal_subtitle">ألا ترغب برؤيته</string>
|
||||||
|
<string name="report_reason_spam">إزعاج</string>
|
||||||
|
<string name="report_reason_spam_subtitle">روابط خبيثة أو تفاعل كاذب أو ردود متكررة</string>
|
||||||
|
<string name="report_reason_violation">ينتهك قواعد الخادم</string>
|
||||||
|
<string name="report_reason_violation_subtitle">تعلم أنه ينتهك قواعد محددة</string>
|
||||||
|
<string name="report_reason_other">شيء آخر</string>
|
||||||
|
<string name="report_reason_other_subtitle">لا تندرج هذه المشكلة ضمن فئات أخرى</string>
|
||||||
|
<string name="report_choose_rule">ما هي القواعد المنتهكة؟</string>
|
||||||
|
<string name="report_choose_rule_subtitle">اختر كل ما ينطبق</string>
|
||||||
|
<string name="report_choose_posts">هل توجد منشورات تدعم صحة هذا البلاغ؟</string>
|
||||||
|
<string name="report_choose_posts_subtitle">اختر كل ما ينطبق</string>
|
||||||
|
<string name="report_comment_title">هل لديك شيء آخر لتخبرنا به؟</string>
|
||||||
|
<string name="report_comment_hint">تعليقات إضافية</string>
|
||||||
|
<string name="sending_report">يرسل البلاغ…</string>
|
||||||
|
<string name="report_sent_title">شُكرًا لَكَ على التبليغ، سَنَنظُرُ فِي هَذَا الأمر.</string>
|
||||||
|
<string name="report_sent_subtitle">في أثناء مراجعتنا للبلاغ، يمكنك اتخاذ إجراء ضد @%s.</string>
|
||||||
|
<string name="unfollow_user">ألغ متابعة %s</string>
|
||||||
|
<string name="unfollow">ألغ المتابعة</string>
|
||||||
|
<string name="mute_user_explain">لن ترى منشوراتهم أو إعادة تدوينهم في التغذية الرئيسية. ولن يعلموا أنهم كتموا.</string>
|
||||||
|
<string name="block_user_explain">لن يتمكنوا من متابعتك أو رؤية منشوراتك، وسيكون بديهيًا لهم أنهم حجبوا.</string>
|
||||||
|
<string name="report_personal_title">لاترغب في مشاهدة هذا؟</string>
|
||||||
|
<string name="report_personal_subtitle">عندما ترى ما لا يعجبك في ماستدون، يمكنك إزالة صاحبها من تجربتك كمستخدم.</string>
|
||||||
|
<string name="back">العودة</string>
|
||||||
|
<string name="instance_catalog_title">يتكوّن ماستدون من مستخدمين موزّعين عبر خوادم مختلفة.</string>
|
||||||
|
<string name="instance_catalog_subtitle">اختر خادمًا بناءً على اهتماماتك، منطقتك أو يمكنك حتى اختيارُ مجتمعٍ ذي غرضٍ عام. وسيضل بامكانك التواصل مع المستخدمين من الخوادم الأخرى.</string>
|
||||||
|
<string name="search_communities">ابحث عن خادم أو أدخل رابطه</string>
|
||||||
|
<string name="instance_rules_title">بعض القواعد الأساسية</string>
|
||||||
|
<string name="instance_rules_subtitle">خذ دقيقة لمراجعة القواعد التي حددها وفرضها مديروا %s.</string>
|
||||||
|
<string name="signup_title">دعنا نجهزك في %s</string>
|
||||||
|
<string name="edit_photo">حرّر</string>
|
||||||
|
<string name="display_name">الاسم العلني</string>
|
||||||
|
<string name="username">اسم المستخدم</string>
|
||||||
|
<string name="email">البريد الإلكتروني</string>
|
||||||
|
<string name="password">كلمة المرور</string>
|
||||||
|
<string name="password_note">ضمّن الأحرف الكبيرة والأحرف الخاصة والأرقام لزيادة قوة كلمة المرور.</string>
|
||||||
|
<string name="category_academia">أكاديمي</string>
|
||||||
|
<string name="category_activism">النشطاء</string>
|
||||||
|
<string name="category_all">الكل</string>
|
||||||
|
<string name="category_art">فنون</string>
|
||||||
|
<string name="category_food">طعام</string>
|
||||||
|
<string name="category_furry">حيوان ذو فرو</string>
|
||||||
|
<string name="category_games">ألعاب</string>
|
||||||
|
<string name="category_general">عام</string>
|
||||||
|
<string name="category_journalism">صحافة</string>
|
||||||
|
<string name="category_lgbt">LGBT</string>
|
||||||
|
<string name="category_music">موسيقى</string>
|
||||||
|
<string name="category_regional">إقليمي</string>
|
||||||
|
<string name="category_tech">تقني</string>
|
||||||
|
<string name="confirm_email_title">شيءٌ أخير</string>
|
||||||
|
<string name="confirm_email_subtitle">أنقر على الرابط المرسل إليك لاستيثاق حسابك.</string>
|
||||||
|
<string name="resend">أعد الإرسال</string>
|
||||||
|
<string name="open_email_app">افتح تطبيق البريد الإلكتروني</string>
|
||||||
|
<string name="resent_email">أُرسلت رسالة التأكيد</string>
|
||||||
|
<string name="compose_hint">عَبِّر عَمَّ يَجُولُ فِي ذِهنِك</string>
|
||||||
|
<string name="content_warning">تحذير من المحتوى</string>
|
||||||
|
<string name="add_image_description">أضف وصفًا للصورة…</string>
|
||||||
|
<string name="retry_upload">حاول الرفع مجددًا</string>
|
||||||
|
<string name="edit_image">حرّر الصورة</string>
|
||||||
|
<string name="save">احفظ</string>
|
||||||
|
<string name="add_alt_text">أضف نصًا بديلًا</string>
|
||||||
|
<string name="alt_text_subtitle">يصف النص البديل محتوى الصور للمكفوفين وضعاف البصر. حاول تضمين أكبر قدر ممكن من التفاصيل ليفهموا السياق.</string>
|
||||||
|
<string name="alt_text_hint">مثال: كلب ينظر حوله بارتياب وعيناه مثبتتان على الكاميرا.</string>
|
||||||
|
<string name="visibility_public">علني</string>
|
||||||
|
<string name="visibility_followers_only">للمُتابِعينَ فقط</string>
|
||||||
|
<string name="visibility_private">لمن ذكرتُهم فقط</string>
|
||||||
|
<string name="search_all">الكل</string>
|
||||||
|
<string name="search_people">أشخاص</string>
|
||||||
|
<string name="recent_searches">عَمَليَّاُت البَحثِ الأخيرَة</string>
|
||||||
|
<string name="step_x_of_n">الخطوة %1$d من %2$d</string>
|
||||||
|
<string name="skip">تخطى</string>
|
||||||
|
<string name="notification_type_follow">متابعُون جُدُد</string>
|
||||||
|
<string name="notification_type_favorite">المفضلة</string>
|
||||||
|
<string name="notification_type_reblog">المعاد تدوينها</string>
|
||||||
|
<string name="notification_type_mention">الذِكر</string>
|
||||||
|
<string name="notification_type_poll">استطلاع رأي</string>
|
||||||
|
<string name="choose_account">اختر حسابًا</string>
|
||||||
|
<string name="err_not_logged_in">يرجى تسجيل الدخول إلى حساب ماستدون أولًا</string>
|
||||||
|
<plurals name="cant_add_more_than_x_attachments">
|
||||||
|
<item quantity="zero">يجب عليك إرفاق ملف</item>
|
||||||
|
<item quantity="one">لا يمكنك إرفاق ملف</item>
|
||||||
|
<item quantity="two">لا يمكنك إرفاق أكثر من ملفين</item>
|
||||||
|
<item quantity="few">لا يمكنك إرفاق أكثر من %d ملفات</item>
|
||||||
|
<item quantity="many">لا يمكنك إرفاق أكثر من %d ملفًا</item>
|
||||||
|
<item quantity="other">لا يمكنك إرفاق أكثر من %d ملف</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="media_attachment_unsupported_type">نوع الملف %s غير مدعوم</string>
|
||||||
|
<string name="media_attachment_too_big">الملف %1$s يتجاوز حدّ %2$s مب</string>
|
||||||
|
<string name="settings_theme">المظهر</string>
|
||||||
|
<string name="theme_auto">تلقائي</string>
|
||||||
|
<string name="theme_light">فاتح</string>
|
||||||
|
<string name="theme_dark">داكن</string>
|
||||||
|
<string name="theme_true_black">الوضع الداكن الحقيقي</string>
|
||||||
|
<string name="settings_behavior">السلوك</string>
|
||||||
|
<string name="settings_gif">تشغيل الصور الرمزية المتحركة والرموز التعبيرية المتحركة</string>
|
||||||
|
<string name="settings_custom_tabs">استخدم المتصفح المضمن</string>
|
||||||
|
<string name="settings_notifications">الإشعارات</string>
|
||||||
|
<string name="notify_me_when">أشعِرني عند قيام</string>
|
||||||
|
<string name="notify_anyone">أيَّ شخصٍ</string>
|
||||||
|
<string name="notify_follower">مُتابِع</string>
|
||||||
|
<string name="notify_followed">شخص أُتابِعُه</string>
|
||||||
|
<string name="notify_none">لَا أحد</string>
|
||||||
|
<string name="notify_favorites">بِالإعْجاب بِمَنشوري</string>
|
||||||
|
<string name="notify_follow">بمتابعتي</string>
|
||||||
|
<string name="notify_reblog">بإعادة تدوين مَنشوري</string>
|
||||||
|
<string name="notify_mention">ذكرني</string>
|
||||||
|
<string name="settings_boring">المنطِقَةُ المُملَّة</string>
|
||||||
|
<string name="settings_account">إعدادات الحساب</string>
|
||||||
|
<string name="settings_contribute">ساهم في ماستدون</string>
|
||||||
|
<string name="settings_tos">شروط الخدمة</string>
|
||||||
|
<string name="settings_privacy_policy">سياسة الخصوصية</string>
|
||||||
|
<string name="settings_spicy">المنطِقَةُ اللَّاذِعَة</string>
|
||||||
|
<string name="settings_clear_cache">امسح التخزين المؤقت للوسائط</string>
|
||||||
|
<string name="settings_app_version">تطبيق ماستدون لأندرويد نسخة %1$s (%2$d)</string>
|
||||||
|
<string name="media_cache_cleared">مُسح التخزين المؤقت للوسائط</string>
|
||||||
|
<string name="confirm_log_out">أمتأكد من الخروج؟</string>
|
||||||
|
<string name="sensitive_content">محتوى حساس</string>
|
||||||
|
<string name="sensitive_content_explain">علّم المؤلف هته الوسائط كحساسة. اضغط لكشفها.</string>
|
||||||
|
<string name="media_hidden">اُنقُر لِلكَشف</string>
|
||||||
|
<string name="avatar_description">انتقل للصفحة الشخصية لـ %s</string>
|
||||||
|
<string name="more_options">مزيد من الخيارات</string>
|
||||||
|
<string name="reveal_content">اكشف المحتوى</string>
|
||||||
|
<string name="hide_content">اخف المحتوى</string>
|
||||||
|
<string name="new_post">منشور جديد</string>
|
||||||
|
<string name="button_reply">ردّ</string>
|
||||||
|
<string name="button_reblog">أعد تدوين</string>
|
||||||
|
<string name="button_favorite">فضّل</string>
|
||||||
|
<string name="button_share">شارك</string>
|
||||||
|
<string name="media_no_description">وسائط بدون وصف</string>
|
||||||
|
<string name="add_media">أضف وسائط</string>
|
||||||
|
<string name="add_poll">أضف استطلاع رأي</string>
|
||||||
|
<string name="emoji">إيموجي</string>
|
||||||
|
<string name="post_visibility">مرئية المنشور</string>
|
||||||
|
<string name="home_timeline">الخيط الزمني الرئيسي</string>
|
||||||
|
<string name="my_profile">ملفي الشخصي</string>
|
||||||
|
<string name="media_viewer">عارض الوسائط</string>
|
||||||
|
<string name="follow_user">تابع %s</string>
|
||||||
|
<string name="unfollowed_user">ألغ متابعة %s</string>
|
||||||
|
<string name="followed_user">أنت تتابع %s</string>
|
||||||
|
<string name="open_in_browser">افتح في المتصفح</string>
|
||||||
|
<string name="hide_boosts_from_user">اخف ما أعاد %s تدوينه</string>
|
||||||
|
<string name="show_boosts_from_user">أظهر ما أعاد %s تدوينه</string>
|
||||||
|
<string name="signup_reason">لماذا ترغب في الانضمام؟</string>
|
||||||
|
<string name="signup_reason_note">هذا سوف يساعدنا في مراجعة تطبيقك.</string>
|
||||||
|
<string name="clear">امسح</string>
|
||||||
|
<string name="profile_header">الصورة الفوقية</string>
|
||||||
|
<string name="profile_picture">صورة الملفّ الشخصي</string>
|
||||||
|
<string name="reorder">أعد الترتيب</string>
|
||||||
|
<string name="download">نزّل</string>
|
||||||
|
<string name="permission_required">يتطلب أذونات</string>
|
||||||
|
<string name="storage_permission_to_download">يحتاج هذا التطبيق أذن الوصول للتخزين لحفظ الملف.</string>
|
||||||
|
<string name="open_settings">افتح الإعدادات</string>
|
||||||
|
<string name="error_saving_file">خطأ أثناء حفظ الملف</string>
|
||||||
|
<string name="file_saved">حُفظ الملف</string>
|
||||||
|
<string name="downloading">ينزّل…</string>
|
||||||
|
<string name="no_app_to_handle_action">لا يوجد تطبيق لمعالجة هذا الإجراء</string>
|
||||||
|
<string name="local_timeline">المجتمع</string>
|
||||||
|
<string name="trending_posts_info_banner">هَذِهِ هِيَ المَنشُوراتُ الَّتي تَكْتَسِبُ شَعبِيَّةً فِي الرُّكنِ الخاصِّ بِكَ مِن مَاستودُون.</string>
|
||||||
|
<string name="trending_hashtags_info_banner">هَذِهِ هِيَ الوُسُومُ الَّتي تَكْتَسِبُ شَعبِيَّةً فِي الرُّكنِ الخاصِّ بِكَ مِن مَاستودُون.</string>
|
||||||
|
<string name="trending_links_info_banner">هَذِهِ هِيَ القِصَصُ الأخبارِيَّةُ المُتَنَاقَلَةُ بِكِثرَةٍ فِي الرُّكنِ الخاصِّ بِكَ مِن مَاستودُون.</string>
|
||||||
|
<string name="local_timeline_info_banner">هذه هي أحدث منشورات المستخدمين المتواجدين على نفس الخادم الذي تستخدمه.</string>
|
||||||
|
<string name="dismiss">رفض</string>
|
||||||
|
<string name="see_new_posts">استعرض المنشورات الجديدة</string>
|
||||||
|
<string name="load_missing_posts">حمّل المَنشورات المَفقودَة</string>
|
||||||
|
<string name="follow_back">رُدّ المتابعة</string>
|
||||||
|
<string name="button_follow_pending">معلق</string>
|
||||||
|
<string name="follows_you">يُتابِعُك</string>
|
||||||
|
<string name="manually_approves_followers">الموافقة اليدوية على طلبات المتابعة</string>
|
||||||
|
<string name="current_account">الحِسابُ الحاليّ</string>
|
||||||
|
<string name="log_out_account">تَسجيلُ الخُرُوجِ مِن %s</string>
|
||||||
|
<!-- translators: %,d is a valid placeholder, it formats the number with locale-dependent grouping separators -->
|
||||||
|
<plurals name="x_followers">
|
||||||
|
<item quantity="zero">ليس له متابِعون</item>
|
||||||
|
<item quantity="one">متابِع واحد</item>
|
||||||
|
<item quantity="two">متابِعان</item>
|
||||||
|
<item quantity="few">%,d متابِعين</item>
|
||||||
|
<item quantity="many">%,d متابِعًا</item>
|
||||||
|
<item quantity="other">%,d متابِع</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_following">
|
||||||
|
<item quantity="zero">ليس له متابَعون</item>
|
||||||
|
<item quantity="one">متابَع واحد</item>
|
||||||
|
<item quantity="two">متابَعان</item>
|
||||||
|
<item quantity="few">%,d متابَعين</item>
|
||||||
|
<item quantity="many">%,d متابَعًا</item>
|
||||||
|
<item quantity="other">%,d متابَع</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_favorites">
|
||||||
|
<item quantity="zero">دون تفضيلات</item>
|
||||||
|
<item quantity="one">تفضيل واحد</item>
|
||||||
|
<item quantity="two">تفضيلان</item>
|
||||||
|
<item quantity="few">%,d تفضيلات</item>
|
||||||
|
<item quantity="many">%,d تفضيلًا</item>
|
||||||
|
<item quantity="other">%,d تفضيل</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_reblogs">
|
||||||
|
<item quantity="zero">لا إعادات تدوين</item>
|
||||||
|
<item quantity="one">إعاد تدوين واحدة</item>
|
||||||
|
<item quantity="two">إعادتا تدوين</item>
|
||||||
|
<item quantity="few">%,d إعادات تدوين</item>
|
||||||
|
<item quantity="many">%,d إعادة تدوين</item>
|
||||||
|
<item quantity="other">%,d إعادة تدوين</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="timestamp_via_app">%1$s عبر %2$s</string>
|
||||||
|
<string name="time_now">الآن</string>
|
||||||
|
<string name="post_info_reblogs">إعادات التدوين</string>
|
||||||
|
<string name="post_info_favorites">المفضلة</string>
|
||||||
|
<string name="edit_history">تاريخ التعديل</string>
|
||||||
|
<string name="last_edit_at_x">آخر تعديل %s</string>
|
||||||
|
<string name="time_just_now">للتوّ</string>
|
||||||
|
<plurals name="x_seconds_ago">
|
||||||
|
<item quantity="zero">منذ %d ثانية</item>
|
||||||
|
<item quantity="one">منذ ثانية</item>
|
||||||
|
<item quantity="two">منذ ثانيتان</item>
|
||||||
|
<item quantity="few">%d ثواني</item>
|
||||||
|
<item quantity="many">منذ %d ثانية</item>
|
||||||
|
<item quantity="other">%d ثواني مضت</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="x_minutes_ago">
|
||||||
|
<item quantity="zero">الان</item>
|
||||||
|
<item quantity="one">منذ دقيقة</item>
|
||||||
|
<item quantity="two">منذ دقيقتان</item>
|
||||||
|
<item quantity="few">%d دقائق مضت</item>
|
||||||
|
<item quantity="many">منذ %d دقائق</item>
|
||||||
|
<item quantity="other">منذ %d دقائق</item>
|
||||||
|
</plurals>
|
||||||
|
<string name="edited_timestamp">عُدّل في %s</string>
|
||||||
|
<string name="edit_original_post">المنشور الأصلي</string>
|
||||||
|
<string name="edit_text_edited">تم تعديل النص</string>
|
||||||
|
<string name="edit_spoiler_added">تم إضافة تحذير المحتوى</string>
|
||||||
|
<string name="edit_spoiler_edited">تم تعديل تحذير المحتوى</string>
|
||||||
|
<string name="edit_spoiler_removed">تم حذف تحذير المحتوى</string>
|
||||||
|
<string name="edit_poll_added">تمت إضافة استطلاع للرأي</string>
|
||||||
|
<string name="edit_poll_edited">تم تعديل الاستطلاع</string>
|
||||||
|
<string name="edit_poll_removed">تمت إزالة الاستطلاع</string>
|
||||||
|
<string name="edit_media_added">تمت إضافة الوسائط</string>
|
||||||
|
<string name="edit_media_removed">تمت إزالة الوسائط</string>
|
||||||
|
<string name="edit_media_reordered">تمت إعادة ترتيب الوسائط</string>
|
||||||
|
<string name="edit_marked_sensitive">مُعَين كحساس</string>
|
||||||
|
<string name="edit_marked_not_sensitive">مُعَين كمنشور غير حساس</string>
|
||||||
|
<string name="edit_multiple_changed">عُدّل المنشور</string>
|
||||||
|
<string name="edit">تعديل</string>
|
||||||
|
<string name="discard_changes">تجاهل التغييرات؟</string>
|
||||||
|
<string name="upload_failed">فشلت عملية التحميل</string>
|
||||||
|
<string name="file_size_bytes">%d بايت</string>
|
||||||
|
<string name="file_size_kb">%.2f كيلوبايت</string>
|
||||||
|
<string name="file_size_mb">%.2f ميغابايت</string>
|
||||||
|
<string name="file_size_gb">%.2f جيجابايت</string>
|
||||||
|
<string name="file_upload_progress">%1$s من %2$s</string>
|
||||||
|
<string name="file_upload_time_remaining">%s متبقية</string>
|
||||||
|
<string name="upload_error_connection_lost">فقد جهازك الاتصال بالإنترنت</string>
|
||||||
|
<string name="upload_processing">قيد المعالجة…</string>
|
||||||
|
<!-- %s is version like 1.2.3 -->
|
||||||
|
<string name="update_available">ماستدون %s للأندرويد جاهز للتنزيل.</string>
|
||||||
|
<!-- %s is version like 1.2.3 -->
|
||||||
|
<string name="update_ready">تم تنزيل ماستدون %s للأندرويد ومستعد لتثبيته.</string>
|
||||||
|
<!-- %s is file size -->
|
||||||
|
<string name="download_update">جارٍ التنزيل (%s)</string>
|
||||||
|
<string name="install_update">تثبيت</string>
|
||||||
|
<string name="privacy_policy_title">ماستدون وخصوصيتك</string>
|
||||||
|
<string name="privacy_policy_subtitle">على الرغم من أن تطبيق ماستدون لا يجمع أي بيانات، فإن الخادم الذي قمت بالتسجيل من خلاله قد تكون له سياسة مختلفة. خذ دقيقة للمراجعة والموافقة على سياسة خصوصية التطبيق ماستدون وسياسة الخصوصية للخادم الخاص بك.</string>
|
||||||
|
<string name="i_agree">أنا مُوافِق</string>
|
||||||
|
<string name="empty_list">هذه القائمة فارغة</string>
|
||||||
|
<string name="confirm_delete_and_redraft">هل أنت متأكد أنك تريد حذف وإعادة صياغة هذا المنشور؟</string>
|
||||||
|
<string name="visibility_unlisted">غير مدرج</string>
|
||||||
|
<string name="list_timelines">القوائم</string>
|
||||||
|
<string name="follow_requests">طلبات المتابعة</string>
|
||||||
|
<string name="instance_signup_closed">هذا الخادم لا يقبل تسجيلات جديدة.</string>
|
||||||
|
<string name="pinned_posts">مدبّس</string>
|
||||||
|
<string name="delete_and_redraft">حذف وإعادة الصياغة</string>
|
||||||
|
<string name="confirm_delete_and_redraft_title">حذف وإعادة صياغة الرسالة</string>
|
||||||
|
<string name="pin_post">تدبيس على الصفحة الشخصية</string>
|
||||||
|
<string name="confirm_pin_post_title">تدبيس الرسالة على الصفحة الشخصية</string>
|
||||||
|
<string name="settings_show_federated_timeline">إظهار الخيط الفديرالي</string>
|
||||||
|
<string name="settings_contribute_fork">المساهمة في Megalodon</string>
|
||||||
|
<string name="accept_follow_request">قبول طلب المتابعة</string>
|
||||||
|
<string name="reject_follow_request">رفض طلب المتابعة</string>
|
||||||
|
<string name="lists_with_user">قوائم بها %s</string>
|
||||||
|
<string name="text_copied">تم النسخ إلى الحافظة</string>
|
||||||
|
<string name="add_bookmark">إضافة إلى الفواصل المرجعية</string>
|
||||||
|
<string name="remove_bookmark">إزالة من الفواصل المرجعية</string>
|
||||||
|
<string name="bookmarks">الفواصل المرجعية</string>
|
||||||
|
<string name="your_favorites">مفضلاتك</string>
|
||||||
|
</resources>
|
||||||
@@ -10,13 +10,11 @@
|
|||||||
<string name="ok">حسنًا</string>
|
<string name="ok">حسنًا</string>
|
||||||
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
<string name="preparing_auth">جَارٍ الإعدَادُ لِلمُصادَقَة…</string>
|
||||||
<string name="finishing_auth">يُنهي المصادقة…</string>
|
<string name="finishing_auth">يُنهي المصادقة…</string>
|
||||||
<string name="user_boosted">أعادَ %s تَدوينَها</string>
|
|
||||||
<string name="in_reply_to">ردًا على %s</string>
|
<string name="in_reply_to">ردًا على %s</string>
|
||||||
<string name="notifications">الإشعارات</string>
|
<string name="notifications">الإشعارات</string>
|
||||||
<string name="user_followed_you">بَدَأ بِمُتابَعَتِك</string>
|
<string name="user_followed_you">بَدَأ بِمُتابَعَتِك</string>
|
||||||
<string name="user_sent_follow_request">أرسَلَ طَلَبًا لِمُتابَعَتِك</string>
|
<string name="user_sent_follow_request">أرسَلَ طَلَبًا لِمُتابَعَتِك</string>
|
||||||
<string name="user_favorited">فَضَّلَ مَنشُورَك</string>
|
<string name="user_favorited">فَضَّلَ مَنشُورَك</string>
|
||||||
<string name="notification_boosted">أعادَ تَدوينَ مَنشُورِك</string>
|
|
||||||
<string name="poll_ended">انتهى استطلاعُ الرأي</string>
|
<string name="poll_ended">انتهى استطلاعُ الرأي</string>
|
||||||
<string name="time_seconds">%d ثا</string>
|
<string name="time_seconds">%d ثا</string>
|
||||||
<string name="time_minutes">%d د</string>
|
<string name="time_minutes">%d د</string>
|
||||||
@@ -222,7 +220,6 @@
|
|||||||
<string name="report_sent_subtitle">في أثناء مراجعتنا للبلاغ، يمكنك اتخاذ إجراء ضد @%s.</string>
|
<string name="report_sent_subtitle">في أثناء مراجعتنا للبلاغ، يمكنك اتخاذ إجراء ضد @%s.</string>
|
||||||
<string name="unfollow_user">ألغ متابعة %s</string>
|
<string name="unfollow_user">ألغ متابعة %s</string>
|
||||||
<string name="unfollow">ألغ المتابعة</string>
|
<string name="unfollow">ألغ المتابعة</string>
|
||||||
<string name="mute_user_explain">لن ترى منشوراتهم أو إعادة تدوينهم في التغذية الرئيسية. ولن يعلموا أنهم كتموا.</string>
|
|
||||||
<string name="block_user_explain">لن يتمكنوا من متابعتك أو رؤية منشوراتك، وسيكون بديهيًا لهم أنهم حجبوا.</string>
|
<string name="block_user_explain">لن يتمكنوا من متابعتك أو رؤية منشوراتك، وسيكون بديهيًا لهم أنهم حجبوا.</string>
|
||||||
<string name="report_personal_title">لاترغب في مشاهدة هذا؟</string>
|
<string name="report_personal_title">لاترغب في مشاهدة هذا؟</string>
|
||||||
<string name="report_personal_subtitle">عندما ترى ما لا يعجبك في ماستدون، يمكنك إزالة صاحبها من تجربتك كمستخدم.</string>
|
<string name="report_personal_subtitle">عندما ترى ما لا يعجبك في ماستدون، يمكنك إزالة صاحبها من تجربتك كمستخدم.</string>
|
||||||
@@ -279,7 +276,6 @@
|
|||||||
<string name="skip">تخطى</string>
|
<string name="skip">تخطى</string>
|
||||||
<string name="notification_type_follow">متابعُون جُدُد</string>
|
<string name="notification_type_follow">متابعُون جُدُد</string>
|
||||||
<string name="notification_type_favorite">المفضلة</string>
|
<string name="notification_type_favorite">المفضلة</string>
|
||||||
<string name="notification_type_reblog">المعاد تدوينها</string>
|
|
||||||
<string name="notification_type_mention">الذِكر</string>
|
<string name="notification_type_mention">الذِكر</string>
|
||||||
<string name="notification_type_poll">استطلاع رأي</string>
|
<string name="notification_type_poll">استطلاع رأي</string>
|
||||||
<string name="choose_account">اختر حسابًا</string>
|
<string name="choose_account">اختر حسابًا</string>
|
||||||
@@ -310,7 +306,6 @@
|
|||||||
<string name="notify_none">لَا أحد</string>
|
<string name="notify_none">لَا أحد</string>
|
||||||
<string name="notify_favorites">بِالإعْجاب بِمَنشوري</string>
|
<string name="notify_favorites">بِالإعْجاب بِمَنشوري</string>
|
||||||
<string name="notify_follow">بمتابعتي</string>
|
<string name="notify_follow">بمتابعتي</string>
|
||||||
<string name="notify_reblog">بإعادة تدوين مَنشوري</string>
|
|
||||||
<string name="notify_mention">بِالإشارَةِ إليّ</string>
|
<string name="notify_mention">بِالإشارَةِ إليّ</string>
|
||||||
<string name="settings_boring">المنطِقَةُ المُملَّة</string>
|
<string name="settings_boring">المنطِقَةُ المُملَّة</string>
|
||||||
<string name="settings_account">إعدادات الحساب</string>
|
<string name="settings_account">إعدادات الحساب</string>
|
||||||
@@ -331,7 +326,6 @@
|
|||||||
<string name="hide_content">اخف المحتوى</string>
|
<string name="hide_content">اخف المحتوى</string>
|
||||||
<string name="new_post">منشور جديد</string>
|
<string name="new_post">منشور جديد</string>
|
||||||
<string name="button_reply">ردّ</string>
|
<string name="button_reply">ردّ</string>
|
||||||
<string name="button_reblog">أعد تدوين</string>
|
|
||||||
<string name="button_favorite">فضّل</string>
|
<string name="button_favorite">فضّل</string>
|
||||||
<string name="button_share">شارك</string>
|
<string name="button_share">شارك</string>
|
||||||
<string name="media_no_description">وسائط بدون وصف</string>
|
<string name="media_no_description">وسائط بدون وصف</string>
|
||||||
@@ -346,8 +340,6 @@
|
|||||||
<string name="unfollowed_user">ألغ متابعة %s</string>
|
<string name="unfollowed_user">ألغ متابعة %s</string>
|
||||||
<string name="followed_user">أنت تتابع %s</string>
|
<string name="followed_user">أنت تتابع %s</string>
|
||||||
<string name="open_in_browser">افتح في المتصفح</string>
|
<string name="open_in_browser">افتح في المتصفح</string>
|
||||||
<string name="hide_boosts_from_user">اخف ما أعاد %s تدوينه</string>
|
|
||||||
<string name="show_boosts_from_user">أظهر ما أعاد %s تدوينه</string>
|
|
||||||
<string name="signup_reason">لماذا تريد الانضمام؟</string>
|
<string name="signup_reason">لماذا تريد الانضمام؟</string>
|
||||||
<string name="signup_reason_note">هذا سوف يساعدنا في مراجعة تطبيقك.</string>
|
<string name="signup_reason_note">هذا سوف يساعدنا في مراجعة تطبيقك.</string>
|
||||||
<string name="clear">امسح</string>
|
<string name="clear">امسح</string>
|
||||||
@@ -401,17 +393,8 @@
|
|||||||
<item quantity="many">%,d تفضيلًا</item>
|
<item quantity="many">%,d تفضيلًا</item>
|
||||||
<item quantity="other">%,d تفضيل</item>
|
<item quantity="other">%,d تفضيل</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
|
||||||
<item quantity="zero">لا إعادات تدوين</item>
|
|
||||||
<item quantity="one">إعاد تدوين واحدة</item>
|
|
||||||
<item quantity="two">إعادتا تدوين</item>
|
|
||||||
<item quantity="few">%,d إعادات تدوين</item>
|
|
||||||
<item quantity="many">%,d إعادة تدوين</item>
|
|
||||||
<item quantity="other">%,d إعادة تدوين</item>
|
|
||||||
</plurals>
|
|
||||||
<string name="timestamp_via_app">%1$s عبر %2$s</string>
|
<string name="timestamp_via_app">%1$s عبر %2$s</string>
|
||||||
<string name="time_now">الآن</string>
|
<string name="time_now">الآن</string>
|
||||||
<string name="post_info_reblogs">إعادات التدوين</string>
|
|
||||||
<string name="post_info_favorites">المفضلة</string>
|
<string name="post_info_favorites">المفضلة</string>
|
||||||
<string name="edit_history">تاريخ التعديل</string>
|
<string name="edit_history">تاريخ التعديل</string>
|
||||||
<string name="last_edit_at_x">آخر تعديل %s</string>
|
<string name="last_edit_at_x">آخر تعديل %s</string>
|
||||||
@@ -478,12 +461,6 @@
|
|||||||
<string name="login_title">مرحبا بك مجددًا</string>
|
<string name="login_title">مرحبا بك مجددًا</string>
|
||||||
<string name="login_subtitle">قم بتسجيل الدخول باستخدام الخادم حيث قمتَ بإنشاء حسابك فيه.</string>
|
<string name="login_subtitle">قم بتسجيل الدخول باستخدام الخادم حيث قمتَ بإنشاء حسابك فيه.</string>
|
||||||
<string name="server_url">رابط الخادم</string>
|
<string name="server_url">رابط الخادم</string>
|
||||||
<string name="welcome_page1_title">ما هو ماستدون؟</string>
|
|
||||||
<string name="welcome_page1_text">تخيل أن لديك عنوان بريد إلكتروني ينتهي بـ @example.com.\n\n رغم ذلك يمكنك إرسال واستقبال رسائل البريد الإلكتروني من أي شخص، حتى إذا كان بريدهم الإلكتروني الخاص ينتهي بـ @gmail.com أو @icloud.com أو @example.com.</string>
|
|
||||||
<string name="welcome_page2_title">ماستدون هكذا.</string>
|
|
||||||
<string name="welcome_page2_text">قد يكون مُعرّفُك @gothgirl654@example.social ، ولكنه بإمكانك متابعة وإعادة تدوين ومحادثة @fallout5ever@example.online.</string>
|
|
||||||
<string name="welcome_page3_title">كيف يمكنني اختيار خادم؟</string>
|
|
||||||
<string name="welcome_page3_text">يختار الأشخاص المختلفون خوادم مختلفة لأي عدد من الأسباب. يعد art.example مكانًا رائعًا للفنانين ، بينما قد يكون glasgow.example اختيارًا جيدًا للاسكتلنديين. \n\n لا يمكنك أن تخطئ في أي من الخوادم التي نوصي بها ، لذلك بغض النظر عن أي واحد تختاره (أو إذا قمت بإدخال الخادم الخاص بك في شريط البحث) ، فلن يفوتك أي شيء في أي مكان.</string>
|
|
||||||
<string name="signup_random_server_explain">سوف نختار خادماً بناءً على لغتك إذا قمت بالمتابعة دون إجراء إختيار.</string>
|
<string name="signup_random_server_explain">سوف نختار خادماً بناءً على لغتك إذا قمت بالمتابعة دون إجراء إختيار.</string>
|
||||||
<string name="server_filter_any_language">أي لغة</string>
|
<string name="server_filter_any_language">أي لغة</string>
|
||||||
<string name="server_filter_instant_signup">تسجيل فوري</string>
|
<string name="server_filter_instant_signup">تسجيل فوري</string>
|
||||||
|
|||||||
@@ -10,13 +10,11 @@
|
|||||||
<string name="ok">Добра</string>
|
<string name="ok">Добра</string>
|
||||||
<string name="preparing_auth">Падрыхтоўка да аўтэнтыфікацыі…</string>
|
<string name="preparing_auth">Падрыхтоўка да аўтэнтыфікацыі…</string>
|
||||||
<string name="finishing_auth">Завяршэнне аўтэнтыфікацыі…</string>
|
<string name="finishing_auth">Завяршэнне аўтэнтыфікацыі…</string>
|
||||||
<string name="user_boosted">%s пашырыў</string>
|
|
||||||
<string name="in_reply_to">У адказ %s</string>
|
<string name="in_reply_to">У адказ %s</string>
|
||||||
<string name="notifications">Апавяшчэнні</string>
|
<string name="notifications">Апавяшчэнні</string>
|
||||||
<string name="user_followed_you">падпісаўся(-лася) на вас</string>
|
<string name="user_followed_you">падпісаўся(-лася) на вас</string>
|
||||||
<string name="user_sent_follow_request">адправіў запыт на падпіску</string>
|
<string name="user_sent_follow_request">адправіў запыт на падпіску</string>
|
||||||
<string name="user_favorited">упадабаў(-ла) ваш допіс</string>
|
<string name="user_favorited">упадабаў(-ла) ваш допіс</string>
|
||||||
<string name="notification_boosted">пашырыў(-ла) ваш допіс</string>
|
|
||||||
<string name="poll_ended">апытанне завершана</string>
|
<string name="poll_ended">апытанне завершана</string>
|
||||||
<string name="time_seconds">%dсек</string>
|
<string name="time_seconds">%dсек</string>
|
||||||
<string name="time_minutes">%dхв</string>
|
<string name="time_minutes">%dхв</string>
|
||||||
@@ -194,7 +192,6 @@
|
|||||||
<string name="report_sent_subtitle">Пакуль мы разглядаем яе, вы можаце прыняць меры супраць %s.</string>
|
<string name="report_sent_subtitle">Пакуль мы разглядаем яе, вы можаце прыняць меры супраць %s.</string>
|
||||||
<string name="unfollow_user">Адпісацца ад %s</string>
|
<string name="unfollow_user">Адпісацца ад %s</string>
|
||||||
<string name="unfollow">Адпісацца</string>
|
<string name="unfollow">Адпісацца</string>
|
||||||
<string name="mute_user_explain">Вы не ўбачыце іх допісы або пашырэнні ў сваёй хатняй стужцы. Яны не даведаюцца, што вы іх ігнаруеце.</string>
|
|
||||||
<string name="block_user_explain">Яны больш не змогуць падпісвацца на вас або бачыць вашыя допісы, але змогуць бачыць, што яны былі заблакіраваны.</string>
|
<string name="block_user_explain">Яны больш не змогуць падпісвацца на вас або бачыць вашыя допісы, але змогуць бачыць, што яны былі заблакіраваны.</string>
|
||||||
<string name="report_personal_title">Не хочаце бачыць гэта?</string>
|
<string name="report_personal_title">Не хочаце бачыць гэта?</string>
|
||||||
<string name="report_personal_subtitle">Калі вы бачыце на Mastodon нешта, што вам не падабаецца, вы можаце выдаліць чалавека са свайго асяроддзя.</string>
|
<string name="report_personal_subtitle">Калі вы бачыце на Mastodon нешта, што вам не падабаецца, вы можаце выдаліць чалавека са свайго асяроддзя.</string>
|
||||||
@@ -203,6 +200,7 @@
|
|||||||
<string name="instance_catalog_subtitle">Выбірайце сервер у залежнасці ад вашых інтарэсаў, рэгіёна або выберыце сервер агульнага прызначэння. Вы па-ранейшаму можаце ўзаемадзейнічаць з усімі, незалежна ад сервера.</string>
|
<string name="instance_catalog_subtitle">Выбірайце сервер у залежнасці ад вашых інтарэсаў, рэгіёна або выберыце сервер агульнага прызначэння. Вы па-ранейшаму можаце ўзаемадзейнічаць з усімі, незалежна ад сервера.</string>
|
||||||
<string name="search_communities">Назва сервера або URL</string>
|
<string name="search_communities">Назва сервера або URL</string>
|
||||||
<string name="instance_rules_title">Правілы сервера</string>
|
<string name="instance_rules_title">Правілы сервера</string>
|
||||||
|
<string name="instance_rules_subtitle">Працягваючы, вы згаджаецеся выконваць правілы, устаноўленыя мадэратарам %s.</string>
|
||||||
<string name="signup_title">Стварыць уліковы запіс</string>
|
<string name="signup_title">Стварыць уліковы запіс</string>
|
||||||
<string name="edit_photo">рэдагаваць</string>
|
<string name="edit_photo">рэдагаваць</string>
|
||||||
<string name="display_name">Імя</string>
|
<string name="display_name">Імя</string>
|
||||||
@@ -226,6 +224,8 @@
|
|||||||
<string name="category_tech">Тэхналогіі</string>
|
<string name="category_tech">Тэхналогіі</string>
|
||||||
<string name="confirm_email_title">Праверце паштовую скрыню</string>
|
<string name="confirm_email_title">Праверце паштовую скрыню</string>
|
||||||
<!-- %s is the email address -->
|
<!-- %s is the email address -->
|
||||||
|
<string name="confirm_email_subtitle">Націсніце на спасылку, якую мы адправілі, каб спраўдзіць %s. Мы вас пачакаем тут.</string>
|
||||||
|
<string name="confirm_email_didnt_get">Не атрымалі спасылку?</string>
|
||||||
<string name="resend">Адправіць паўторна</string>
|
<string name="resend">Адправіць паўторна</string>
|
||||||
<string name="open_email_app">Адкрыць праграму для пошты</string>
|
<string name="open_email_app">Адкрыць праграму для пошты</string>
|
||||||
<string name="resent_email">Электронны ліст з пацвярджэннем адпраўлены</string>
|
<string name="resent_email">Электронны ліст з пацвярджэннем адпраўлены</string>
|
||||||
@@ -248,7 +248,6 @@
|
|||||||
<string name="skip">Прапусціць</string>
|
<string name="skip">Прапусціць</string>
|
||||||
<string name="notification_type_follow">Новыя падпісчыкі</string>
|
<string name="notification_type_follow">Новыя падпісчыкі</string>
|
||||||
<string name="notification_type_favorite">Абраныя</string>
|
<string name="notification_type_favorite">Абраныя</string>
|
||||||
<string name="notification_type_reblog">Пашырэнні</string>
|
|
||||||
<string name="notification_type_mention">Згадванні</string>
|
<string name="notification_type_mention">Згадванні</string>
|
||||||
<string name="notification_type_poll">Апытанні</string>
|
<string name="notification_type_poll">Апытанні</string>
|
||||||
<string name="choose_account">Выберыце ўліковы запіс</string>
|
<string name="choose_account">Выберыце ўліковы запіс</string>
|
||||||
@@ -277,7 +276,6 @@
|
|||||||
<string name="notify_none">ніхто</string>
|
<string name="notify_none">ніхто</string>
|
||||||
<string name="notify_favorites">Дадае мой допіс у абранае</string>
|
<string name="notify_favorites">Дадае мой допіс у абранае</string>
|
||||||
<string name="notify_follow">Падпісаўся на мяне</string>
|
<string name="notify_follow">Падпісаўся на мяне</string>
|
||||||
<string name="notify_reblog">Пашырае мой допіс</string>
|
|
||||||
<string name="notify_mention">Згадвае мяне</string>
|
<string name="notify_mention">Згадвае мяне</string>
|
||||||
<string name="settings_boring">Нудная зона</string>
|
<string name="settings_boring">Нудная зона</string>
|
||||||
<string name="settings_account">Налады ўліковага запісу</string>
|
<string name="settings_account">Налады ўліковага запісу</string>
|
||||||
@@ -298,7 +296,6 @@
|
|||||||
<string name="hide_content">Схаваць змест</string>
|
<string name="hide_content">Схаваць змест</string>
|
||||||
<string name="new_post">Новы допіс</string>
|
<string name="new_post">Новы допіс</string>
|
||||||
<string name="button_reply">Адказаць</string>
|
<string name="button_reply">Адказаць</string>
|
||||||
<string name="button_reblog">Пашырыць</string>
|
|
||||||
<string name="button_favorite">Абранае</string>
|
<string name="button_favorite">Абранае</string>
|
||||||
<string name="button_share">Абагуліць</string>
|
<string name="button_share">Абагуліць</string>
|
||||||
<string name="media_no_description">Медыя без апісання</string>
|
<string name="media_no_description">Медыя без апісання</string>
|
||||||
@@ -312,9 +309,9 @@
|
|||||||
<string name="follow_user">Падпісацца на %s</string>
|
<string name="follow_user">Падпісацца на %s</string>
|
||||||
<string name="unfollowed_user">Адпісацца ад %s</string>
|
<string name="unfollowed_user">Адпісацца ад %s</string>
|
||||||
<string name="followed_user">Цяпер вы падпісаны на %s</string>
|
<string name="followed_user">Цяпер вы падпісаны на %s</string>
|
||||||
|
<string name="following_user_requested">Запытана падпісацца на %s</string>
|
||||||
<string name="open_in_browser">Адкрыць у браўзеры</string>
|
<string name="open_in_browser">Адкрыць у браўзеры</string>
|
||||||
<string name="hide_boosts_from_user">Схаваць пашырэнні ад %s</string>
|
<string name="signup_reason">Чаму вы хочаце далучыцца?</string>
|
||||||
<string name="show_boosts_from_user">Паказаць пашырэнні ад %s</string>
|
|
||||||
<string name="signup_reason_note">Гэта дапаможа нам разгледзець вашу заяўку.</string>
|
<string name="signup_reason_note">Гэта дапаможа нам разгледзець вашу заяўку.</string>
|
||||||
<string name="clear">Ачысціць</string>
|
<string name="clear">Ачысціць</string>
|
||||||
<string name="profile_header">Відарыс шапкі</string>
|
<string name="profile_header">Відарыс шапкі</string>
|
||||||
@@ -361,15 +358,8 @@
|
|||||||
<item quantity="many">%,d абраных</item>
|
<item quantity="many">%,d абраных</item>
|
||||||
<item quantity="other">%,d абраных</item>
|
<item quantity="other">%,d абраных</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
|
||||||
<item quantity="one">%,d рэпост</item>
|
|
||||||
<item quantity="few">%,d рэпосты</item>
|
|
||||||
<item quantity="many">%,d пашырэнняў</item>
|
|
||||||
<item quantity="other">%,d пашырэнняў</item>
|
|
||||||
</plurals>
|
|
||||||
<string name="timestamp_via_app">%1$s праз %2$s</string>
|
<string name="timestamp_via_app">%1$s праз %2$s</string>
|
||||||
<string name="time_now">толькі што</string>
|
<string name="time_now">толькі што</string>
|
||||||
<string name="post_info_reblogs">Пашырэнні</string>
|
|
||||||
<string name="post_info_favorites">Абраныя</string>
|
<string name="post_info_favorites">Абраныя</string>
|
||||||
<string name="edit_history">Гісторыя рэдагавання</string>
|
<string name="edit_history">Гісторыя рэдагавання</string>
|
||||||
<string name="last_edit_at_x">Апошняе рэдагаванне %s</string>
|
<string name="last_edit_at_x">Апошняе рэдагаванне %s</string>
|
||||||
@@ -419,6 +409,8 @@
|
|||||||
<!-- %s is file size -->
|
<!-- %s is file size -->
|
||||||
<string name="download_update">Спампаваць (%s)</string>
|
<string name="download_update">Спампаваць (%s)</string>
|
||||||
<string name="install_update">Усталяваць</string>
|
<string name="install_update">Усталяваць</string>
|
||||||
|
<string name="privacy_policy_title">Ваша прыватнасць</string>
|
||||||
|
<string name="privacy_policy_subtitle">Нягледзячы на тое, што праграма Mastodon не збірае даных, сервер, на якім вы рэгіструецеся, можа мець іншую палітыку.\n\nКалі вы адмовіцеся ад палітыкі %s, вы можаце вярнуцца і выбраць іншы сервер.</string>
|
||||||
<string name="i_agree">Я згодны</string>
|
<string name="i_agree">Я згодны</string>
|
||||||
<string name="empty_list">Гэты ліст пусты</string>
|
<string name="empty_list">Гэты ліст пусты</string>
|
||||||
<string name="instance_signup_closed">Гэты сервер не прымае новыя рэгістрацыі.</string>
|
<string name="instance_signup_closed">Гэты сервер не прымае новыя рэгістрацыі.</string>
|
||||||
@@ -430,20 +422,35 @@
|
|||||||
<string name="login_title">З вяртаннем</string>
|
<string name="login_title">З вяртаннем</string>
|
||||||
<string name="login_subtitle">Увайдзіце з дапамогай сервера, на якім вы стварылі свой уліковы запіс.</string>
|
<string name="login_subtitle">Увайдзіце з дапамогай сервера, на якім вы стварылі свой уліковы запіс.</string>
|
||||||
<string name="server_url">URL-адрас сервера</string>
|
<string name="server_url">URL-адрас сервера</string>
|
||||||
<string name="welcome_page1_text">Уявіце, што ў вас ёсць адрас электроннай пошты, які заканчваецца на @example.com.\n\nВы па-ранейшаму можаце адпраўляць і атрымліваць электронныя лісты ад каго захочаце, нават калі іх электронная пошта заканчваецца на @gmail.com, @icloud.com або @example.com.</string>
|
<string name="signup_random_server_explain">Мы абярэм сервер на аснове вашай мовы, калі вы працягнеце без выбару.</string>
|
||||||
<string name="welcome_page2_title">Mastodon такі.</string>
|
|
||||||
<string name="welcome_page2_text">Ваш ідэнтыфікатар можа быць @gothgirl654@example.social, але вы ўсё яшчэ можаце падпісвацца, пашыраць і перапісвацца з @fallout5ever@example.online.</string>
|
|
||||||
<string name="welcome_page3_title">Як выбраць сервер?</string>
|
|
||||||
<string name="welcome_page3_text">Розныя людзі выбіраюць розныя серверы па розных прычынах. art.example з\'яўляецца выдатным месцам для мастакоў, у той час як glasgow.example можа быць добрым выбарам для шатландцаў.\n\nВы не памыліцеся ні з адным з нашых рэкамендаваных сервераў, так што незалежна ад таго, які вы выбераце (або калі ўведзяце ваш уласны ў радку пошуку сервера), вы нідзе нічога не прапусціце.</string>
|
|
||||||
<string name="server_filter_any_language">Любая мова</string>
|
<string name="server_filter_any_language">Любая мова</string>
|
||||||
|
<string name="server_filter_instant_signup">Імгненная рэгістрацыя</string>
|
||||||
|
<string name="server_filter_manual_review">Ручная праверка</string>
|
||||||
|
<string name="server_filter_any_signup_speed">Любая хуткасць рэгістрацыі</string>
|
||||||
<string name="server_filter_region_europe">Еўропа</string>
|
<string name="server_filter_region_europe">Еўропа</string>
|
||||||
<string name="server_filter_region_north_america">Паўночная Амерыка</string>
|
<string name="server_filter_region_north_america">Паўночная Амерыка</string>
|
||||||
<string name="server_filter_region_south_america">Паўднёвая Амерыка</string>
|
<string name="server_filter_region_south_america">Паўднёвая Амерыка</string>
|
||||||
<string name="server_filter_region_africa">Афрыка</string>
|
<string name="server_filter_region_africa">Афрыка</string>
|
||||||
<string name="server_filter_region_asia">Азія</string>
|
<string name="server_filter_region_asia">Азія</string>
|
||||||
<string name="server_filter_region_oceania">Акіянія</string>
|
<string name="server_filter_region_oceania">Акіянія</string>
|
||||||
|
<string name="not_accepting_new_members">Не прымае новых удзельнікаў</string>
|
||||||
|
<string name="category_special_interests">Асаблівыя інтарэсы</string>
|
||||||
|
<string name="signup_passwords_dont_match">Паролі не супадаюць</string>
|
||||||
|
<string name="pick_server_for_me">Падбяры для мяне</string>
|
||||||
|
<string name="profile_add_row">Дадаць радок</string>
|
||||||
|
<string name="profile_setup">Налады профілю</string>
|
||||||
|
<string name="profile_setup_subtitle">Вы можаце завяршыць гэта пазней на ўкладцы Профіль.</string>
|
||||||
|
<string name="profile_setup_explanation">Вы можаце дадаць да чатырох палёў профіля для ўсяго, што хочаце. Месцазнаходжанне, спасылкі, займеннікі - няма мяжы магчымасцям.</string>
|
||||||
|
<string name="popular_on_mastodon">Папулярна на Mastodon</string>
|
||||||
|
<string name="follow_all">Падпісацца на ўсіх</string>
|
||||||
|
<string name="server_rules_disagree">Не згодны</string>
|
||||||
|
<string name="privacy_policy_explanation">Мы нічога не збіраем і не апрацоўваем.</string>
|
||||||
<!-- %s is server domain -->
|
<!-- %s is server domain -->
|
||||||
|
<string name="server_policy_disagree">Не згодны з %s</string>
|
||||||
|
<string name="profile_bio">Пра мяне</string>
|
||||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||||
|
<string name="sending_follows">Падпісваемся…</string>
|
||||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||||
|
<string name="signup_email_domain_blocked">%1$s не прымае рэгістрацыю ад %2$s. Паспрабуйце іншы <a>выберыце іншы сервер</a>.</string>
|
||||||
<string name="signup_username_taken">Гэта імя карыстальніка занята.</string>
|
<string name="signup_username_taken">Гэта імя карыстальніка занята.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
<string name="user_followed_you">আপনাকে ফলো করেছেন</string>
|
<string name="user_followed_you">আপনাকে ফলো করেছেন</string>
|
||||||
<string name="user_sent_follow_request">ফলো করার জন্য অনুরোধ পাঠানো হয়েছে</string>
|
<string name="user_sent_follow_request">ফলো করার জন্য অনুরোধ পাঠানো হয়েছে</string>
|
||||||
<string name="user_favorited">আপনার পোস্টটি পছন্দ করেছেন</string>
|
<string name="user_favorited">আপনার পোস্টটি পছন্দ করেছেন</string>
|
||||||
<string name="notification_boosted">আপনার পোস্টের প্রচার করা হয়েছে</string>
|
|
||||||
<string name="poll_ended">ভোট শেষ</string>
|
<string name="poll_ended">ভোট শেষ</string>
|
||||||
<string name="time_seconds">%d সে.</string>
|
<string name="time_seconds">%d সে.</string>
|
||||||
<string name="time_minutes">%d মি.</string>
|
<string name="time_minutes">%d মি.</string>
|
||||||
|
|||||||
@@ -123,7 +123,6 @@
|
|||||||
<string name="report_sent_subtitle">Dok ovo razmatramo, možete poduzeti potrebno za %s.</string>
|
<string name="report_sent_subtitle">Dok ovo razmatramo, možete poduzeti potrebno za %s.</string>
|
||||||
<string name="unfollow_user">Prestani pratiti %s</string>
|
<string name="unfollow_user">Prestani pratiti %s</string>
|
||||||
<string name="unfollow">Prestani pratiti</string>
|
<string name="unfollow">Prestani pratiti</string>
|
||||||
<string name="mute_user_explain">Nećete vidjeti objave i odgovore na vašem zidu. Osoba neče znati da ste je isključili.</string>
|
|
||||||
<string name="block_user_explain">Neće moći više pratiti vaše objave, ali mogu vidjeti ako su blokirani.</string>
|
<string name="block_user_explain">Neće moći više pratiti vaše objave, ali mogu vidjeti ako su blokirani.</string>
|
||||||
<string name="report_personal_title">Ne želite ovo vidjeti?</string>
|
<string name="report_personal_title">Ne želite ovo vidjeti?</string>
|
||||||
<string name="report_personal_subtitle">Kada vidite nešto nepoželjno na Mastodon-u, možete blokirati odredjeni profil.</string>
|
<string name="report_personal_subtitle">Kada vidite nešto nepoželjno na Mastodon-u, možete blokirati odredjeni profil.</string>
|
||||||
@@ -193,7 +192,6 @@
|
|||||||
<string name="notify_none">nikoga</string>
|
<string name="notify_none">nikoga</string>
|
||||||
<string name="notify_favorites">Svidjanje objave</string>
|
<string name="notify_favorites">Svidjanje objave</string>
|
||||||
<string name="notify_follow">Prati me</string>
|
<string name="notify_follow">Prati me</string>
|
||||||
<string name="notify_reblog">Ponovio/la moju objavu</string>
|
|
||||||
<string name="notify_mention">Spominjanje</string>
|
<string name="notify_mention">Spominjanje</string>
|
||||||
<string name="settings_boring">Zona dosade</string>
|
<string name="settings_boring">Zona dosade</string>
|
||||||
<string name="settings_account">Postavke računa</string>
|
<string name="settings_account">Postavke računa</string>
|
||||||
@@ -214,7 +212,6 @@
|
|||||||
<string name="hide_content">Sakrij sadžaj</string>
|
<string name="hide_content">Sakrij sadžaj</string>
|
||||||
<string name="new_post">Nova objava</string>
|
<string name="new_post">Nova objava</string>
|
||||||
<string name="button_reply">Odgovori</string>
|
<string name="button_reply">Odgovori</string>
|
||||||
<string name="button_reblog">Dupliraj</string>
|
|
||||||
<string name="button_favorite">Svidja mi se</string>
|
<string name="button_favorite">Svidja mi se</string>
|
||||||
<string name="button_share">Dijeli</string>
|
<string name="button_share">Dijeli</string>
|
||||||
<string name="media_no_description">Medija bez opisa</string>
|
<string name="media_no_description">Medija bez opisa</string>
|
||||||
|
|||||||
@@ -10,13 +10,11 @@
|
|||||||
<string name="ok">D\'acord</string>
|
<string name="ok">D\'acord</string>
|
||||||
<string name="preparing_auth">Preparant l\'autenticació…</string>
|
<string name="preparing_auth">Preparant l\'autenticació…</string>
|
||||||
<string name="finishing_auth">Finalitzant l\'autenticació…</string>
|
<string name="finishing_auth">Finalitzant l\'autenticació…</string>
|
||||||
<string name="user_boosted">%s ha impulsat</string>
|
|
||||||
<string name="in_reply_to">En resposta a %s</string>
|
<string name="in_reply_to">En resposta a %s</string>
|
||||||
<string name="notifications">Notificacions</string>
|
<string name="notifications">Notificacions</string>
|
||||||
<string name="user_followed_you">t\'ha seguit</string>
|
<string name="user_followed_you">t\'ha seguit</string>
|
||||||
<string name="user_sent_follow_request">ha sol·licitat seguir-te</string>
|
<string name="user_sent_follow_request">ha sol·licitat seguir-te</string>
|
||||||
<string name="user_favorited">ha afavorit la teva publicació</string>
|
<string name="user_favorited">ha afavorit la teva publicació</string>
|
||||||
<string name="notification_boosted">ha impulsat la teva publicació</string>
|
|
||||||
<string name="poll_ended">l\'enquesta ha finalitzat</string>
|
<string name="poll_ended">l\'enquesta ha finalitzat</string>
|
||||||
<string name="time_seconds">%d s</string>
|
<string name="time_seconds">%d s</string>
|
||||||
<string name="time_minutes">%d min</string>
|
<string name="time_minutes">%d min</string>
|
||||||
@@ -166,7 +164,6 @@
|
|||||||
<string name="report_sent_subtitle">Mentre ho revisem, pots prendre mesures contra %s.</string>
|
<string name="report_sent_subtitle">Mentre ho revisem, pots prendre mesures contra %s.</string>
|
||||||
<string name="unfollow_user">Deixar de seguir %s</string>
|
<string name="unfollow_user">Deixar de seguir %s</string>
|
||||||
<string name="unfollow">Deixar de seguir</string>
|
<string name="unfollow">Deixar de seguir</string>
|
||||||
<string name="mute_user_explain">No veuràs les seves publicacions o impulsos a la teva línia de temps personal. No sabran que han estat silenciats.</string>
|
|
||||||
<string name="block_user_explain">Ja no podran seguir ni veure les teves publicacions, però poden veure si han estat bloquejats.</string>
|
<string name="block_user_explain">Ja no podran seguir ni veure les teves publicacions, però poden veure si han estat bloquejats.</string>
|
||||||
<string name="report_personal_title">No vols veure això?</string>
|
<string name="report_personal_title">No vols veure això?</string>
|
||||||
<string name="report_personal_subtitle">Quan veus alguna cosa que no t\'agrada a Mastodon, pots eliminar la persona de la vostra experiència.</string>
|
<string name="report_personal_subtitle">Quan veus alguna cosa que no t\'agrada a Mastodon, pots eliminar la persona de la vostra experiència.</string>
|
||||||
@@ -221,7 +218,6 @@
|
|||||||
<string name="skip">Omet</string>
|
<string name="skip">Omet</string>
|
||||||
<string name="notification_type_follow">Seguidors nous</string>
|
<string name="notification_type_follow">Seguidors nous</string>
|
||||||
<string name="notification_type_favorite">Favorits</string>
|
<string name="notification_type_favorite">Favorits</string>
|
||||||
<string name="notification_type_reblog">Impulsos</string>
|
|
||||||
<string name="notification_type_mention">Mencions</string>
|
<string name="notification_type_mention">Mencions</string>
|
||||||
<string name="notification_type_poll">Enquestes</string>
|
<string name="notification_type_poll">Enquestes</string>
|
||||||
<string name="choose_account">Selecciona un compte</string>
|
<string name="choose_account">Selecciona un compte</string>
|
||||||
@@ -248,7 +244,6 @@
|
|||||||
<string name="notify_none">ningú</string>
|
<string name="notify_none">ningú</string>
|
||||||
<string name="notify_favorites">Ha afavorit la meva publicació</string>
|
<string name="notify_favorites">Ha afavorit la meva publicació</string>
|
||||||
<string name="notify_follow">Em segueix</string>
|
<string name="notify_follow">Em segueix</string>
|
||||||
<string name="notify_reblog">Impulsa la meva publicació</string>
|
|
||||||
<string name="notify_mention">Em menciona</string>
|
<string name="notify_mention">Em menciona</string>
|
||||||
<string name="settings_boring">La zona avorrida</string>
|
<string name="settings_boring">La zona avorrida</string>
|
||||||
<string name="settings_account">Configuració del compte</string>
|
<string name="settings_account">Configuració del compte</string>
|
||||||
@@ -269,7 +264,6 @@
|
|||||||
<string name="hide_content">Amaga el contingut</string>
|
<string name="hide_content">Amaga el contingut</string>
|
||||||
<string name="new_post">Nova publicació</string>
|
<string name="new_post">Nova publicació</string>
|
||||||
<string name="button_reply">Respon</string>
|
<string name="button_reply">Respon</string>
|
||||||
<string name="button_reblog">Impulsa</string>
|
|
||||||
<string name="button_favorite">Favorit</string>
|
<string name="button_favorite">Favorit</string>
|
||||||
<string name="button_share">Comparteix</string>
|
<string name="button_share">Comparteix</string>
|
||||||
<string name="media_no_description">Multimèdia sense descripció</string>
|
<string name="media_no_description">Multimèdia sense descripció</string>
|
||||||
@@ -284,8 +278,6 @@
|
|||||||
<string name="unfollowed_user">S\'ha deixat de seguir %s</string>
|
<string name="unfollowed_user">S\'ha deixat de seguir %s</string>
|
||||||
<string name="followed_user">Ara estàs seguint %s</string>
|
<string name="followed_user">Ara estàs seguint %s</string>
|
||||||
<string name="open_in_browser">Obre al navegador</string>
|
<string name="open_in_browser">Obre al navegador</string>
|
||||||
<string name="hide_boosts_from_user">Amaga els impulsos de %s</string>
|
|
||||||
<string name="show_boosts_from_user">Mostra els impulsos de %s</string>
|
|
||||||
<string name="signup_reason_note">Això ens ajudarà a revisar la teva petició.</string>
|
<string name="signup_reason_note">Això ens ajudarà a revisar la teva petició.</string>
|
||||||
<string name="clear">Esborra</string>
|
<string name="clear">Esborra</string>
|
||||||
<string name="profile_header">Imatge de capçalera</string>
|
<string name="profile_header">Imatge de capçalera</string>
|
||||||
@@ -326,13 +318,8 @@
|
|||||||
<item quantity="one">%,d favorit</item>
|
<item quantity="one">%,d favorit</item>
|
||||||
<item quantity="other">%,d favorits</item>
|
<item quantity="other">%,d favorits</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
|
||||||
<item quantity="one">%,d impuls</item>
|
|
||||||
<item quantity="other">%,d impulsos</item>
|
|
||||||
</plurals>
|
|
||||||
<string name="timestamp_via_app">%1$s través de %2$s</string>
|
<string name="timestamp_via_app">%1$s través de %2$s</string>
|
||||||
<string name="time_now">ara</string>
|
<string name="time_now">ara</string>
|
||||||
<string name="post_info_reblogs">Impulsos</string>
|
|
||||||
<string name="post_info_favorites">Favorits</string>
|
<string name="post_info_favorites">Favorits</string>
|
||||||
<string name="edit_history">Editar l’historial</string>
|
<string name="edit_history">Editar l’historial</string>
|
||||||
<string name="last_edit_at_x">Darrera edició: %s</string>
|
<string name="last_edit_at_x">Darrera edició: %s</string>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
<string name="sk_translated_using">Traduït amb %s</string>
|
<string name="sk_translated_using">Traduït amb %s</string>
|
||||||
<string name="sk_post_language">Llengua: %s</string>
|
<string name="sk_post_language">Llengua: %s</string>
|
||||||
<string name="sk_available_languages">Llengües disponibles</string>
|
<string name="sk_available_languages">Llengües disponibles</string>
|
||||||
<string name="sk_language_name">%s (%s)</string>
|
<string name="sk_language_name">%1$s (%2$s)</string>
|
||||||
<string name="sk_confirm_clear_recent_languages">Segur que vols esborrar les llengües recents\?</string>
|
<string name="sk_confirm_clear_recent_languages">Segur que vols esborrar les llengües recents\?</string>
|
||||||
<string name="sk_welcome_text">El tauró et saluda! Per a començar, introdueix el domini de la instància a continuació.</string>
|
<string name="sk_welcome_text">El tauró et saluda! Per a començar, introdueix el domini de la instància a continuació.</string>
|
||||||
<string name="sk_tabs_disable_swipe">Desactiva el desplaçament entre pestanyes</string>
|
<string name="sk_tabs_disable_swipe">Desactiva el desplaçament entre pestanyes</string>
|
||||||
|
|||||||
@@ -10,13 +10,11 @@
|
|||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="preparing_auth">Příprava na autentizaci…</string>
|
<string name="preparing_auth">Příprava na autentizaci…</string>
|
||||||
<string name="finishing_auth">Dokončení autentizace…</string>
|
<string name="finishing_auth">Dokončení autentizace…</string>
|
||||||
<string name="user_boosted">Uživatel %s boostnul</string>
|
|
||||||
<string name="in_reply_to">V odpovědi na %s</string>
|
<string name="in_reply_to">V odpovědi na %s</string>
|
||||||
<string name="notifications">Upozornění</string>
|
<string name="notifications">Upozornění</string>
|
||||||
<string name="user_followed_you">vás začal(a) sledovat</string>
|
<string name="user_followed_you">vás začal(a) sledovat</string>
|
||||||
<string name="user_sent_follow_request">vám poslal(a) žádost o sledování</string>
|
<string name="user_sent_follow_request">vám poslal(a) žádost o sledování</string>
|
||||||
<string name="user_favorited">si oblíbil(a) váš příspěvek</string>
|
<string name="user_favorited">si oblíbil(a) váš příspěvek</string>
|
||||||
<string name="notification_boosted">boostnul(a) váš příspěvek</string>
|
|
||||||
<string name="poll_ended">anketa skončila</string>
|
<string name="poll_ended">anketa skončila</string>
|
||||||
<string name="time_seconds">%d s</string>
|
<string name="time_seconds">%d s</string>
|
||||||
<string name="time_minutes">%d m</string>
|
<string name="time_minutes">%d m</string>
|
||||||
@@ -194,14 +192,22 @@
|
|||||||
<string name="report_sent_subtitle">Zatímco to posuzujeme, můžete podniknout akce proti %s.</string>
|
<string name="report_sent_subtitle">Zatímco to posuzujeme, můžete podniknout akce proti %s.</string>
|
||||||
<string name="unfollow_user">Přestat sledovat %s</string>
|
<string name="unfollow_user">Přestat sledovat %s</string>
|
||||||
<string name="unfollow">Přestat sledovat</string>
|
<string name="unfollow">Přestat sledovat</string>
|
||||||
<string name="mute_user_explain">Neuvidíte příspěvky nebo boosty tohoto uživatele ve svém domovském kanálu. Nebude vědět, že je skryt.</string>
|
|
||||||
<string name="block_user_explain">Tento uživatel vás již nebude moci sledovat ani vidět vaše příspěvky, ale může zjistit, že je blokován.</string>
|
<string name="block_user_explain">Tento uživatel vás již nebude moci sledovat ani vidět vaše příspěvky, ale může zjistit, že je blokován.</string>
|
||||||
<string name="report_personal_title">Nechcete tohle vidět?</string>
|
<string name="report_personal_title">Nechcete tohle vidět?</string>
|
||||||
<string name="report_personal_subtitle">Když uvidíte něco, co se vám nelíbí na Mastodonu, můžete odstranit tuto osobu ze svého zážitku.</string>
|
<string name="report_personal_subtitle">Když uvidíte něco, co se vám nelíbí na Mastodonu, můžete odstranit tuto osobu ze svého zážitku.</string>
|
||||||
<string name="back">Zpět</string>
|
<string name="back">Zpět</string>
|
||||||
<string name="instance_catalog_title">Mastodon tvoří uživatelé z různých serverů.</string>
|
<string name="instance_catalog_title">Mastodon tvoří uživatelé z různých serverů.</string>
|
||||||
<string name="instance_catalog_subtitle">Vyberte si server podle na svých zájmů, regionu nebo obecného účelu. Stále se můžete spojit se všemi bez ohledu na server.</string>
|
<string name="instance_catalog_subtitle">Vyberte si server podle na svých zájmů, regionu nebo obecného účelu. Stále se můžete spojit se všemi bez ohledu na server.</string>
|
||||||
|
<string name="search_communities">Název nebo URL serveru</string>
|
||||||
|
<string name="instance_rules_title">Pravidla serveru</string>
|
||||||
|
<string name="instance_rules_subtitle">Pokračováním souhlasíte s následujícími pravidly, která jsou nastavena a prosazována moderátory %s.</string>
|
||||||
|
<string name="signup_title">Vytvořit účet</string>
|
||||||
<string name="edit_photo">upravit</string>
|
<string name="edit_photo">upravit</string>
|
||||||
|
<string name="display_name">Jméno</string>
|
||||||
|
<string name="username">Uživatelské jméno</string>
|
||||||
|
<string name="email">E-mail</string>
|
||||||
|
<string name="password">Heslo</string>
|
||||||
|
<string name="confirm_password">Potvrdit heslo</string>
|
||||||
<string name="password_note">Použijte velká písmena, speciální znaky a čísla, abyste zvýšili sílu hesla.</string>
|
<string name="password_note">Použijte velká písmena, speciální znaky a čísla, abyste zvýšili sílu hesla.</string>
|
||||||
<string name="category_academia">Akademická sféra</string>
|
<string name="category_academia">Akademická sféra</string>
|
||||||
<string name="category_activism">Aktivismus</string>
|
<string name="category_activism">Aktivismus</string>
|
||||||
@@ -216,7 +222,10 @@
|
|||||||
<string name="category_music">Hudba</string>
|
<string name="category_music">Hudba</string>
|
||||||
<string name="category_regional">Regionální</string>
|
<string name="category_regional">Regionální</string>
|
||||||
<string name="category_tech">Technologie</string>
|
<string name="category_tech">Technologie</string>
|
||||||
|
<string name="confirm_email_title">Zkontrolujte si příchozí poštu</string>
|
||||||
<!-- %s is the email address -->
|
<!-- %s is the email address -->
|
||||||
|
<string name="confirm_email_subtitle">Klepněte na odkaz, který jsme vám poslali, abyste ověřili %s. Budeme tu na vás čekat.</string>
|
||||||
|
<string name="confirm_email_didnt_get">Nedostali jste odkaz?</string>
|
||||||
<string name="resend">Poslat znovu</string>
|
<string name="resend">Poslat znovu</string>
|
||||||
<string name="open_email_app">Otevřít e-mailovou aplikaci</string>
|
<string name="open_email_app">Otevřít e-mailovou aplikaci</string>
|
||||||
<string name="resent_email">Potvrzující e-mail byl odeslán</string>
|
<string name="resent_email">Potvrzující e-mail byl odeslán</string>
|
||||||
@@ -239,7 +248,6 @@
|
|||||||
<string name="skip">Přeskočit</string>
|
<string name="skip">Přeskočit</string>
|
||||||
<string name="notification_type_follow">Noví sledující</string>
|
<string name="notification_type_follow">Noví sledující</string>
|
||||||
<string name="notification_type_favorite">Oblíbené</string>
|
<string name="notification_type_favorite">Oblíbené</string>
|
||||||
<string name="notification_type_reblog">Boosty</string>
|
|
||||||
<string name="notification_type_mention">Zmínky</string>
|
<string name="notification_type_mention">Zmínky</string>
|
||||||
<string name="notification_type_poll">Ankety</string>
|
<string name="notification_type_poll">Ankety</string>
|
||||||
<string name="choose_account">Vybrat účet</string>
|
<string name="choose_account">Vybrat účet</string>
|
||||||
@@ -268,7 +276,6 @@
|
|||||||
<string name="notify_none">nikoho</string>
|
<string name="notify_none">nikoho</string>
|
||||||
<string name="notify_favorites">Oblíbí si můj příspěvek</string>
|
<string name="notify_favorites">Oblíbí si můj příspěvek</string>
|
||||||
<string name="notify_follow">Začne mě sledovat</string>
|
<string name="notify_follow">Začne mě sledovat</string>
|
||||||
<string name="notify_reblog">Boostne můj příspěvek</string>
|
|
||||||
<string name="notify_mention">Zmíní mě</string>
|
<string name="notify_mention">Zmíní mě</string>
|
||||||
<string name="settings_boring">Nudná část</string>
|
<string name="settings_boring">Nudná část</string>
|
||||||
<string name="settings_account">Nastavení účtu</string>
|
<string name="settings_account">Nastavení účtu</string>
|
||||||
@@ -289,7 +296,6 @@
|
|||||||
<string name="hide_content">Skrýt obsah</string>
|
<string name="hide_content">Skrýt obsah</string>
|
||||||
<string name="new_post">Nový příspěvek</string>
|
<string name="new_post">Nový příspěvek</string>
|
||||||
<string name="button_reply">Odpovědět</string>
|
<string name="button_reply">Odpovědět</string>
|
||||||
<string name="button_reblog">Boostnout</string>
|
|
||||||
<string name="button_favorite">Oblíbit</string>
|
<string name="button_favorite">Oblíbit</string>
|
||||||
<string name="button_share">Sdílet</string>
|
<string name="button_share">Sdílet</string>
|
||||||
<string name="media_no_description">Média bez popisu</string>
|
<string name="media_no_description">Média bez popisu</string>
|
||||||
@@ -303,9 +309,9 @@
|
|||||||
<string name="follow_user">Sledovat %s</string>
|
<string name="follow_user">Sledovat %s</string>
|
||||||
<string name="unfollowed_user">Sledování %s bylo zrušeno</string>
|
<string name="unfollowed_user">Sledování %s bylo zrušeno</string>
|
||||||
<string name="followed_user">Nyní sledujete %s</string>
|
<string name="followed_user">Nyní sledujete %s</string>
|
||||||
|
<string name="following_user_requested">Požádáno o sledování %s</string>
|
||||||
<string name="open_in_browser">Otevřít v prohlížeči</string>
|
<string name="open_in_browser">Otevřít v prohlížeči</string>
|
||||||
<string name="hide_boosts_from_user">Skrýt boosty od %s</string>
|
<string name="signup_reason">Proč se chcete připojit?</string>
|
||||||
<string name="show_boosts_from_user">Zobrazit boosty od %s</string>
|
|
||||||
<string name="signup_reason_note">Toto nám pomůže posoudit vaši žádost.</string>
|
<string name="signup_reason_note">Toto nám pomůže posoudit vaši žádost.</string>
|
||||||
<string name="clear">Vyčistit</string>
|
<string name="clear">Vyčistit</string>
|
||||||
<string name="profile_header">Obrázek v záhlaví</string>
|
<string name="profile_header">Obrázek v záhlaví</string>
|
||||||
@@ -352,15 +358,8 @@
|
|||||||
<item quantity="many">%,d oblíbení</item>
|
<item quantity="many">%,d oblíbení</item>
|
||||||
<item quantity="other">%,d oblíbení</item>
|
<item quantity="other">%,d oblíbení</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
|
||||||
<item quantity="one">%,d boostnul</item>
|
|
||||||
<item quantity="few">%,d boosty</item>
|
|
||||||
<item quantity="many">%,d boostů</item>
|
|
||||||
<item quantity="other">%,d boostů</item>
|
|
||||||
</plurals>
|
|
||||||
<string name="timestamp_via_app">%1$s přes %2$s</string>
|
<string name="timestamp_via_app">%1$s přes %2$s</string>
|
||||||
<string name="time_now">teď</string>
|
<string name="time_now">teď</string>
|
||||||
<string name="post_info_reblogs">Boosty</string>
|
|
||||||
<string name="post_info_favorites">Oblíbení</string>
|
<string name="post_info_favorites">Oblíbení</string>
|
||||||
<string name="edit_history">Historie úprav</string>
|
<string name="edit_history">Historie úprav</string>
|
||||||
<string name="last_edit_at_x">Poslední úprava %s</string>
|
<string name="last_edit_at_x">Poslední úprava %s</string>
|
||||||
@@ -410,6 +409,8 @@
|
|||||||
<!-- %s is file size -->
|
<!-- %s is file size -->
|
||||||
<string name="download_update">Stáhnout (%s)</string>
|
<string name="download_update">Stáhnout (%s)</string>
|
||||||
<string name="install_update">Instalovat</string>
|
<string name="install_update">Instalovat</string>
|
||||||
|
<string name="privacy_policy_title">Vaše soukromí</string>
|
||||||
|
<string name="privacy_policy_subtitle">Přestože aplikace Mastodon neshromažďuje žádná data, server, který se přihlásíte, může mít jiné zásady.\n\nPokud nesouhlasíte se zásadami pro %s, můžete se vrátit a vybrat jiný server.</string>
|
||||||
<string name="i_agree">Souhlasím</string>
|
<string name="i_agree">Souhlasím</string>
|
||||||
<string name="empty_list">Tento seznam je prázdný</string>
|
<string name="empty_list">Tento seznam je prázdný</string>
|
||||||
<string name="instance_signup_closed">Tento server nepřijímá nové registrace.</string>
|
<string name="instance_signup_closed">Tento server nepřijímá nové registrace.</string>
|
||||||
@@ -421,12 +422,35 @@
|
|||||||
<string name="login_title">Vítejte zpět</string>
|
<string name="login_title">Vítejte zpět</string>
|
||||||
<string name="login_subtitle">Přihlaste se pomocí serveru, kde jste vytvořili svůj účet.</string>
|
<string name="login_subtitle">Přihlaste se pomocí serveru, kde jste vytvořili svůj účet.</string>
|
||||||
<string name="server_url">URL serveru</string>
|
<string name="server_url">URL serveru</string>
|
||||||
<string name="welcome_page1_text">Představte si, že máte e-mailovou adresu, která končí @example.com.\n\nStále můžete od kohokoliv odesílat a přijímat e-maily, i když jejich e-mail končí na @gmail.com nebo @icloud.com nebo @example.com.</string>
|
<string name="signup_random_server_explain">Pokud budete pokračovat bez výběru, vybereme server založený na vašem jazyce.</string>
|
||||||
<string name="welcome_page2_title">Takový je Mastodon.</string>
|
<string name="server_filter_any_language">Libovolný jazyk</string>
|
||||||
<string name="welcome_page2_text">Vaše uživatelské jméno může být @gothgirl654@example.social, ale stále můžete sledovat, boostovat a chatovat s @fallout5ever@example.online.</string>
|
<string name="server_filter_instant_signup">Okamžitá registrace</string>
|
||||||
<string name="welcome_page3_title">Jak si vybrat server?</string>
|
<string name="server_filter_manual_review">Ruční kontrola</string>
|
||||||
<string name="welcome_page3_text">Různí lidé si vybírají různé servery z různých důvodů. Art.example je skvělým místem pro umělce, zatímco glasgow.example může být dobrou volbou pro Skoty.\n\nS žádným z našich doporučených serverů nemůžete udělat chybu, takže bez ohledu na to, který z nich si vyberete (nebo pokud zadáte svůj vlastní do vyhledávacího řádku serveru), nikde neprohloupíte.</string>
|
<string name="server_filter_any_signup_speed">Jakákoliv rychlost registrace</string>
|
||||||
|
<string name="server_filter_region_europe">Evropa</string>
|
||||||
|
<string name="server_filter_region_north_america">Severní Amerika</string>
|
||||||
|
<string name="server_filter_region_south_america">Jižní Amerika</string>
|
||||||
|
<string name="server_filter_region_africa">Afrika</string>
|
||||||
|
<string name="server_filter_region_asia">Asie</string>
|
||||||
|
<string name="server_filter_region_oceania">Oceánie</string>
|
||||||
|
<string name="not_accepting_new_members">Nepřijímá nové členy</string>
|
||||||
|
<string name="category_special_interests">Speciální zájmy</string>
|
||||||
|
<string name="signup_passwords_dont_match">Hesla se neshodují</string>
|
||||||
|
<string name="pick_server_for_me">Vybrat pro mě</string>
|
||||||
|
<string name="profile_add_row">Přidat řádek</string>
|
||||||
|
<string name="profile_setup">Nastavení profilu</string>
|
||||||
|
<string name="profile_setup_subtitle">Toto můžete vždy dokončit později v záložce Profil.</string>
|
||||||
|
<string name="profile_setup_explanation">Můžete přidat až čtyři pole profilu pro cokoliv, co chcete. Umístění, odkazy, oslovení — limitem je obloha.</string>
|
||||||
|
<string name="popular_on_mastodon">Populární na Mastodonu</string>
|
||||||
|
<string name="follow_all">Sledovat všechny</string>
|
||||||
|
<string name="server_rules_disagree">Nesouhlasit</string>
|
||||||
|
<string name="privacy_policy_explanation">Zkráceně: nic nesbíráme a nezpracováváme.</string>
|
||||||
<!-- %s is server domain -->
|
<!-- %s is server domain -->
|
||||||
|
<string name="server_policy_disagree">Nesouhlasit s %s</string>
|
||||||
|
<string name="profile_bio">O vás</string>
|
||||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||||
|
<string name="sending_follows">Sledování uživatelů…</string>
|
||||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||||
|
<string name="signup_email_domain_blocked">%1$s neumožňuje registraci od %2$s. Zkuste jiný nebo <a>vyberte jiný server</a>.</string>
|
||||||
|
<string name="signup_username_taken">Toto uživatelské jméno je obsazené.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -40,7 +40,7 @@
|
|||||||
<string name="sk_no_update_available">Dim diweddariad ar gael</string>
|
<string name="sk_no_update_available">Dim diweddariad ar gael</string>
|
||||||
<string name="sk_check_for_update">Gwirio am ddiweddariad</string>
|
<string name="sk_check_for_update">Gwirio am ddiweddariad</string>
|
||||||
<string name="sk_poll_allow_multiple">Caniatáu mwy nag un dewis</string>
|
<string name="sk_poll_allow_multiple">Caniatáu mwy nag un dewis</string>
|
||||||
<string name="sk_language_name">%s (%s)</string>
|
<string name="sk_language_name">%1$s (%2$s)</string>
|
||||||
<string name="sk_tabs_disable_swipe">Analluogi llusgo rhwng tabiau</string>
|
<string name="sk_tabs_disable_swipe">Analluogi llusgo rhwng tabiau</string>
|
||||||
<string name="sk_settings_posting">Dewisiadau postio</string>
|
<string name="sk_settings_posting">Dewisiadau postio</string>
|
||||||
<string name="sk_settings_rules">Rheolau</string>
|
<string name="sk_settings_rules">Rheolau</string>
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
<string name="ok">Ok</string>
|
<string name="ok">Ok</string>
|
||||||
<string name="preparing_auth">Forbereder godkendelse…</string>
|
<string name="preparing_auth">Forbereder godkendelse…</string>
|
||||||
<string name="finishing_auth">Afslutter godkendelse…</string>
|
<string name="finishing_auth">Afslutter godkendelse…</string>
|
||||||
<string name="user_boosted">%s boostede</string>
|
<string name="user_boosted">%s fremhævede</string>
|
||||||
<string name="in_reply_to">Som svar til %s</string>
|
<string name="in_reply_to">Som svar til %s</string>
|
||||||
<string name="notifications">Meddelelser</string>
|
<string name="notifications">Meddelelser</string>
|
||||||
<string name="user_followed_you">begyndte at følge dig</string>
|
<string name="user_followed_you">begyndte at følge dig</string>
|
||||||
<string name="user_sent_follow_request">sendte dig en følgeanmodning</string>
|
<string name="user_sent_follow_request">sendte dig en følgeanmodning</string>
|
||||||
<string name="user_favorited">favoritmarkerede dit indlæg</string>
|
<string name="user_favorited">favoritmarkerede dit indlæg</string>
|
||||||
<string name="notification_boosted">boostede dit indlæg</string>
|
<string name="notification_boosted">fremhævede dit indlæg</string>
|
||||||
<string name="poll_ended">afstemning afsluttet</string>
|
<string name="poll_ended">afstemning afsluttet</string>
|
||||||
<string name="time_seconds">%ds</string>
|
<string name="time_seconds">%ds</string>
|
||||||
<string name="time_minutes">%d m</string>
|
<string name="time_minutes">%d m</string>
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
<string name="report_sent_subtitle">Mens dette gennemgås, kan du selv bortfiltrere indlæg fra %s.</string>
|
<string name="report_sent_subtitle">Mens dette gennemgås, kan du selv bortfiltrere indlæg fra %s.</string>
|
||||||
<string name="unfollow_user">Følg ikke længere %s</string>
|
<string name="unfollow_user">Følg ikke længere %s</string>
|
||||||
<string name="unfollow">Følg ikke længere</string>
|
<string name="unfollow">Følg ikke længere</string>
|
||||||
<string name="mute_user_explain">Du vil ikke se den pågældendes indlæg eller boosts i din tidslinje. Vedkommende vil ikke få besked om dæmpningen.</string>
|
<string name="mute_user_explain">Du vil ikke se den pågældendes indlæg eller fremhævninger i din tidslinje. Vedkommende vil ikke få besked om dæmpningen.</string>
|
||||||
<string name="block_user_explain">Vedkommende vil ikke længere kunne følge dig eller se dine indlæg, men vedkommende kan se blokeringen.</string>
|
<string name="block_user_explain">Vedkommende vil ikke længere kunne følge dig eller se dine indlæg, men vedkommende kan se blokeringen.</string>
|
||||||
<string name="report_personal_title">Ønsker du ikke at se dette?</string>
|
<string name="report_personal_title">Ønsker du ikke at se dette?</string>
|
||||||
<string name="report_personal_subtitle">Når du ser noget, du ikke kan lide på Mastodon, kan du fjerne personen fra din tidslinje.</string>
|
<string name="report_personal_subtitle">Når du ser noget, du ikke kan lide på Mastodon, kan du fjerne personen fra din tidslinje.</string>
|
||||||
@@ -223,7 +223,7 @@
|
|||||||
<string name="skip">Spring over</string>
|
<string name="skip">Spring over</string>
|
||||||
<string name="notification_type_follow">Nye følgere</string>
|
<string name="notification_type_follow">Nye følgere</string>
|
||||||
<string name="notification_type_favorite">Favoritmarkeringer</string>
|
<string name="notification_type_favorite">Favoritmarkeringer</string>
|
||||||
<string name="notification_type_reblog">Boosts</string>
|
<string name="notification_type_reblog">Fremhævninger</string>
|
||||||
<string name="notification_type_mention">Omtaler</string>
|
<string name="notification_type_mention">Omtaler</string>
|
||||||
<string name="notification_type_poll">Afstemninger</string>
|
<string name="notification_type_poll">Afstemninger</string>
|
||||||
<string name="choose_account">Vælg konto</string>
|
<string name="choose_account">Vælg konto</string>
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
<string name="notify_none">ingen</string>
|
<string name="notify_none">ingen</string>
|
||||||
<string name="notify_favorites">Favoritmarkerede mit indlæg</string>
|
<string name="notify_favorites">Favoritmarkerede mit indlæg</string>
|
||||||
<string name="notify_follow">Følger mig</string>
|
<string name="notify_follow">Følger mig</string>
|
||||||
<string name="notify_reblog">Booster mit indlæg</string>
|
<string name="notify_reblog">Fremhæver mit indlæg</string>
|
||||||
<string name="notify_mention">Nævner mig</string>
|
<string name="notify_mention">Nævner mig</string>
|
||||||
<string name="settings_boring">Den kedelige zone</string>
|
<string name="settings_boring">Den kedelige zone</string>
|
||||||
<string name="settings_account">Kontoindstillinger</string>
|
<string name="settings_account">Kontoindstillinger</string>
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
<string name="hide_content">Skjul indhold</string>
|
<string name="hide_content">Skjul indhold</string>
|
||||||
<string name="new_post">Nyt indlæg</string>
|
<string name="new_post">Nyt indlæg</string>
|
||||||
<string name="button_reply">Svar</string>
|
<string name="button_reply">Svar</string>
|
||||||
<string name="button_reblog">Boost</string>
|
<string name="button_reblog">Fremhæv</string>
|
||||||
<string name="button_favorite">Favorit</string>
|
<string name="button_favorite">Favorit</string>
|
||||||
<string name="button_share">Del</string>
|
<string name="button_share">Del</string>
|
||||||
<string name="media_no_description">Medier uden beskrivelse</string>
|
<string name="media_no_description">Medier uden beskrivelse</string>
|
||||||
@@ -285,9 +285,10 @@
|
|||||||
<string name="follow_user">Følg %s</string>
|
<string name="follow_user">Følg %s</string>
|
||||||
<string name="unfollowed_user">Følg ikke længere %s</string>
|
<string name="unfollowed_user">Følg ikke længere %s</string>
|
||||||
<string name="followed_user">Du følger nu %s</string>
|
<string name="followed_user">Du følger nu %s</string>
|
||||||
|
<string name="following_user_requested">Anmodede om at følge %s</string>
|
||||||
<string name="open_in_browser">Åbn i browser</string>
|
<string name="open_in_browser">Åbn i browser</string>
|
||||||
<string name="hide_boosts_from_user">Skjul boosts fra %s</string>
|
<string name="hide_boosts_from_user">Skjul fremhævninger fra %s</string>
|
||||||
<string name="show_boosts_from_user">Vis boosts fra %s</string>
|
<string name="show_boosts_from_user">Vis fremhævninger fra %s</string>
|
||||||
<string name="signup_reason">Hvorfor ønsker du at tilmelde dig?</string>
|
<string name="signup_reason">Hvorfor ønsker du at tilmelde dig?</string>
|
||||||
<string name="signup_reason_note">Dette hjælper os med at vurdere din ansøgning.</string>
|
<string name="signup_reason_note">Dette hjælper os med at vurdere din ansøgning.</string>
|
||||||
<string name="clear">Ryd</string>
|
<string name="clear">Ryd</string>
|
||||||
@@ -330,12 +331,12 @@
|
|||||||
<item quantity="other">%,d favoritmarkeringer</item>
|
<item quantity="other">%,d favoritmarkeringer</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
<plurals name="x_reblogs">
|
||||||
<item quantity="one">%,d boost</item>
|
<item quantity="one">%,d indlæg</item>
|
||||||
<item quantity="other">%,d boosts</item>
|
<item quantity="other">%,d indlæg</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="timestamp_via_app">%1$s via %2$s</string>
|
<string name="timestamp_via_app">%1$s via %2$s</string>
|
||||||
<string name="time_now">nu</string>
|
<string name="time_now">nu</string>
|
||||||
<string name="post_info_reblogs">Boosts</string>
|
<string name="post_info_reblogs">Fremhævninger</string>
|
||||||
<string name="post_info_favorites">Favoritmarkeringer</string>
|
<string name="post_info_favorites">Favoritmarkeringer</string>
|
||||||
<string name="edit_history">Rediger historik</string>
|
<string name="edit_history">Rediger historik</string>
|
||||||
<string name="last_edit_at_x">Senest ændret: %s</string>
|
<string name="last_edit_at_x">Senest ændret: %s</string>
|
||||||
@@ -382,6 +383,7 @@
|
|||||||
<string name="download_update">Download (%s)</string>
|
<string name="download_update">Download (%s)</string>
|
||||||
<string name="install_update">Installer</string>
|
<string name="install_update">Installer</string>
|
||||||
<string name="privacy_policy_title">Dit privatliv</string>
|
<string name="privacy_policy_title">Dit privatliv</string>
|
||||||
|
<string name="privacy_policy_subtitle">Selvom Mastodon-appen ikke indsamler data, kan den server du tilmelder dig gennem, have en anden politik.\n\nHvis du er uenig i politikken for %s, kan du gå tilbage og vælge en anden server.</string>
|
||||||
<string name="i_agree">Jeg accepterer</string>
|
<string name="i_agree">Jeg accepterer</string>
|
||||||
<string name="empty_list">Denne liste er tom</string>
|
<string name="empty_list">Denne liste er tom</string>
|
||||||
<string name="instance_signup_closed">Denne server er ikke åben for nye tilmeldinger.</string>
|
<string name="instance_signup_closed">Denne server er ikke åben for nye tilmeldinger.</string>
|
||||||
@@ -393,12 +395,6 @@
|
|||||||
<string name="login_title">Velkommen tilbage</string>
|
<string name="login_title">Velkommen tilbage</string>
|
||||||
<string name="login_subtitle">Log ind med serveren hvor du oprettede din bruger.</string>
|
<string name="login_subtitle">Log ind med serveren hvor du oprettede din bruger.</string>
|
||||||
<string name="server_url">Server-URL</string>
|
<string name="server_url">Server-URL</string>
|
||||||
<string name="welcome_page1_title">Hvad er Mastodon?</string>
|
|
||||||
<string name="welcome_page1_text">Det svarer til at du har en e-mailadresse, der slutter med @eksempel.dk.\n\nAlligevel kan du stadig både sende og modtage e-mails fra alle, selv om deres e-mail ender på @gmail.com eller @icloud.com eller @eksempel.dk.</string>
|
|
||||||
<string name="welcome_page2_title">Mastodon er ligesådan.</string>
|
|
||||||
<string name="welcome_page2_text">Dit brugernavn kan være @goth654@eksempel.social, men du kan stadig følge, booste, og chatte med @denanden@eksempel.online.</string>
|
|
||||||
<string name="welcome_page3_title">Hvordan vælger jeg en server?</string>
|
|
||||||
<string name="welcome_page3_text">Forskellige mennesker vælger forskellige servere af mange forskellige grunde. art.example er et godt sted for kunstnere, mens glasgow.example kan være et godt pluk for skotter.\n\nDu kan ikke gå galt i byen med en af vores anbefalingsservere, så uanset hvilken du vælger (eller hvis du indtaster din egen i serversøgelinjen), vil du aldrig gå glip af noget nogen steder.</string>
|
|
||||||
<string name="signup_random_server_explain">Vi vælger en server baseret på dit sprog, hvis du fortsætter uden at foretage et valg.</string>
|
<string name="signup_random_server_explain">Vi vælger en server baseret på dit sprog, hvis du fortsætter uden at foretage et valg.</string>
|
||||||
<string name="server_filter_any_language">Hvilket som helst sprog</string>
|
<string name="server_filter_any_language">Hvilket som helst sprog</string>
|
||||||
<string name="server_filter_instant_signup">Øjeblikkelig tilmelding</string>
|
<string name="server_filter_instant_signup">Øjeblikkelig tilmelding</string>
|
||||||
@@ -421,7 +417,31 @@
|
|||||||
<string name="popular_on_mastodon">Populært på Mastodon</string>
|
<string name="popular_on_mastodon">Populært på Mastodon</string>
|
||||||
<string name="follow_all">Følg alle</string>
|
<string name="follow_all">Følg alle</string>
|
||||||
<string name="server_rules_disagree">Ikke enig</string>
|
<string name="server_rules_disagree">Ikke enig</string>
|
||||||
|
<string name="privacy_policy_explanation">TL;DR: Vi indsamler eller behandler ikke noget.</string>
|
||||||
<!-- %s is server domain -->
|
<!-- %s is server domain -->
|
||||||
|
<string name="server_policy_disagree">Uenig med %s</string>
|
||||||
|
<string name="profile_bio">Biografi</string>
|
||||||
<!-- Shown in a progress dialog when you tap "follow all" -->
|
<!-- Shown in a progress dialog when you tap "follow all" -->
|
||||||
|
<string name="sending_follows">Følger brugere …</string>
|
||||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||||
|
<string name="signup_email_domain_blocked">%1$s tillader ikke tilmeldinger fra %2$s. Prøv en anden eller <a>vælg en anden server</a>.</string>
|
||||||
|
<string name="signup_username_taken">Brugernavnet er allerede i brug.</string>
|
||||||
|
<string name="spoiler_show">Vis alligevel</string>
|
||||||
|
<string name="spoiler_hide">Genskjul</string>
|
||||||
|
<string name="poll_multiple_choice">Vælg en eller flere</string>
|
||||||
|
<string name="save_changes">Gem ændringer</string>
|
||||||
|
<string name="profile_featured">Fremhævet</string>
|
||||||
|
<string name="profile_timeline">Tidslinje</string>
|
||||||
|
<string name="view_all">Se alle</string>
|
||||||
|
<string name="profile_endorsed_accounts">Konti</string>
|
||||||
|
<string name="verified_link">Bekræftet link</string>
|
||||||
|
<string name="show">Vis</string>
|
||||||
|
<string name="hide">Skjul</string>
|
||||||
|
<string name="join_default_server">Tilmeld dig %s</string>
|
||||||
|
<string name="signup_or_login">eller</string>
|
||||||
|
<string name="learn_more">Få mere at vide</string>
|
||||||
|
<string name="welcome_to_mastodon">Velkommen til Mastodon</string>
|
||||||
|
<string name="welcome_paragraph1">Mastodon er et decentraliseret socialt netværk, hvilket betyder at ingen enkelt virksomhed styrer det. Det består af mange uafhængige servere, alle forbundet sammen.</string>
|
||||||
|
<string name="what_are_servers">Hvad er servere?</string>
|
||||||
|
<string name="welcome_paragraph2"><![CDATA[Alle Mastodon-konti har plads på en server. Hver server har sine egne værdier, regler og administratorer. Ligegyldigt hvilken server du vælger, kan du følge og interagere med folk på alle andre servere.]]></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -10,13 +10,13 @@
|
|||||||
<string name="ok">OK</string>
|
<string name="ok">OK</string>
|
||||||
<string name="preparing_auth">Authentifizierung wird vorbereitet …</string>
|
<string name="preparing_auth">Authentifizierung wird vorbereitet …</string>
|
||||||
<string name="finishing_auth">Authentifizierung wird abgeschlossen …</string>
|
<string name="finishing_auth">Authentifizierung wird abgeschlossen …</string>
|
||||||
<string name="user_boosted">%s hat diesen Beitrag geteilt</string>
|
<string name="user_boosted">%s hat geteilt</string>
|
||||||
<string name="in_reply_to">Als Antwort auf %s</string>
|
<string name="in_reply_to">Als Antwort auf %s</string>
|
||||||
<string name="notifications">Benachrichtigungen</string>
|
<string name="notifications">Benachrichtigungen</string>
|
||||||
<string name="user_followed_you">folgt dir jetzt</string>
|
<string name="user_followed_you">folgt dir jetzt</string>
|
||||||
<string name="user_sent_follow_request">hat dir eine Follower-Anfrage gesendet</string>
|
<string name="user_sent_follow_request">hat dir eine Follower-Anfrage gesendet</string>
|
||||||
<string name="user_favorited">favorisierte</string>
|
<string name="user_favorited">favorisierte</string>
|
||||||
<string name="notification_boosted">teilte</string>
|
<string name="notification_boosted">teilte deinen Beitrag</string>
|
||||||
<string name="poll_ended">Abstimmung beendet</string>
|
<string name="poll_ended">Abstimmung beendet</string>
|
||||||
<string name="time_seconds">vor %d Sekunden</string>
|
<string name="time_seconds">vor %d Sekunden</string>
|
||||||
<string name="time_minutes">vor %d Minuten</string>
|
<string name="time_minutes">vor %d Minuten</string>
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
<string name="notify_none">niemand</string>
|
<string name="notify_none">niemand</string>
|
||||||
<string name="notify_favorites">meinen Beitrag favorisiert</string>
|
<string name="notify_favorites">meinen Beitrag favorisiert</string>
|
||||||
<string name="notify_follow">mir folgt</string>
|
<string name="notify_follow">mir folgt</string>
|
||||||
<string name="notify_reblog">einen meiner Beiträge geteilt hat</string>
|
<string name="notify_reblog">Teilte meinen Beitrag</string>
|
||||||
<string name="notify_mention">mich erwähnt</string>
|
<string name="notify_mention">mich erwähnt</string>
|
||||||
<string name="settings_boring">Langweiliges</string>
|
<string name="settings_boring">Langweiliges</string>
|
||||||
<string name="settings_account">Kontoeinstellungen</string>
|
<string name="settings_account">Kontoeinstellungen</string>
|
||||||
@@ -287,8 +287,8 @@
|
|||||||
<string name="followed_user">Du folgst nun %s</string>
|
<string name="followed_user">Du folgst nun %s</string>
|
||||||
<string name="following_user_requested">Deine Follower-Anfrage an %s wurde gesendet</string>
|
<string name="following_user_requested">Deine Follower-Anfrage an %s wurde gesendet</string>
|
||||||
<string name="open_in_browser">Im Browser öffnen</string>
|
<string name="open_in_browser">Im Browser öffnen</string>
|
||||||
<string name="hide_boosts_from_user">geteilte Beiträge von %s ausblenden</string>
|
<string name="hide_boosts_from_user">Geteilte Beiträge von %s verstecken</string>
|
||||||
<string name="show_boosts_from_user">geteilte Beiträge von %s anzeigen</string>
|
<string name="show_boosts_from_user">Geteilte Beiträge von %s anzeigen</string>
|
||||||
<string name="signup_reason">Warum möchtest du beitreten?</string>
|
<string name="signup_reason">Warum möchtest du beitreten?</string>
|
||||||
<string name="signup_reason_note">Das erleichtert uns die Prüfung deiner Anmeldung.</string>
|
<string name="signup_reason_note">Das erleichtert uns die Prüfung deiner Anmeldung.</string>
|
||||||
<string name="clear">Leeren</string>
|
<string name="clear">Leeren</string>
|
||||||
@@ -331,8 +331,8 @@
|
|||||||
<item quantity="other">%,d × favorisiert</item>
|
<item quantity="other">%,d × favorisiert</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="x_reblogs">
|
<plurals name="x_reblogs">
|
||||||
<item quantity="one">%,d × geteilt</item>
|
<item quantity="one">%,d geteilter Beitrag</item>
|
||||||
<item quantity="other">%,d × geteilt</item>
|
<item quantity="other">%,d geteilte Beiträge</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="timestamp_via_app">%1$s via %2$s</string>
|
<string name="timestamp_via_app">%1$s via %2$s</string>
|
||||||
<string name="time_now">jetzt</string>
|
<string name="time_now">jetzt</string>
|
||||||
@@ -395,12 +395,6 @@
|
|||||||
<string name="login_title">Willkommen zurück</string>
|
<string name="login_title">Willkommen zurück</string>
|
||||||
<string name="login_subtitle">Melde dich mit dem Server an, auf dem du dein Konto erstellt hast.</string>
|
<string name="login_subtitle">Melde dich mit dem Server an, auf dem du dein Konto erstellt hast.</string>
|
||||||
<string name="server_url">Serveradresse</string>
|
<string name="server_url">Serveradresse</string>
|
||||||
<string name="welcome_page1_title">Was ist Mastodon?</string>
|
|
||||||
<string name="welcome_page1_text">Angenommen, du hast eine E-Mail-Adresse, die mit @example.com endet.\n\nDu kannst immer noch E-Mails von allen empfangen, auch wenn deren E-Mail-Adresse mit @gmail.com, @icloud.com oder @example.com endet.</string>
|
|
||||||
<string name="welcome_page2_title">Mastodon ist genau so.</string>
|
|
||||||
<string name="welcome_page2_text">Dein Nutzer*innenname könnte @GothGirl654@example.social sein, aber du kannst trotzdem @fallout5ever@example.online folgen, deren Beiträge teilen und dich mit der Person unterhalten.</string>
|
|
||||||
<string name="welcome_page3_title">Wie wähle ich einen Server aus?</string>
|
|
||||||
<string name="welcome_page3_text">Unterschiedliche Menschen wählen aus verschiedenen Gründen unterschiedliche Server. art.example ist ein toller Ort für Künstler*innen, während glasgow.example eine gute Wahl für Schott*innen sein könnte.\n\nWähle nach Möglichkeit einen kleinen Server aus, mit dessen Regeln du dich wohl fühlst und der dir vertrauenswürdig erscheint (über die Server-Suchleiste kannst du dich direkt mit dem Server deines Vertrauens verbinden).</string>
|
|
||||||
<string name="signup_random_server_explain">Wenn du ohne Auswahl fortfährst, wählen wir einen Server in deiner Sprache aus.</string>
|
<string name="signup_random_server_explain">Wenn du ohne Auswahl fortfährst, wählen wir einen Server in deiner Sprache aus.</string>
|
||||||
<string name="server_filter_any_language">Alle Sprachen</string>
|
<string name="server_filter_any_language">Alle Sprachen</string>
|
||||||
<string name="server_filter_instant_signup">Schnellregistrierung</string>
|
<string name="server_filter_instant_signup">Schnellregistrierung</string>
|
||||||
@@ -432,4 +426,20 @@
|
|||||||
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
<!-- %1$s is server domain, %2$s is email domain. You can reorder these placeholders to fit your language better. -->
|
||||||
<string name="signup_email_domain_blocked">%1$s lässt keine Anmeldungen von %2$s zu. Versuche einen anderen oder <a>wähle einen anderen Server</a>.</string>
|
<string name="signup_email_domain_blocked">%1$s lässt keine Anmeldungen von %2$s zu. Versuche einen anderen oder <a>wähle einen anderen Server</a>.</string>
|
||||||
<string name="signup_username_taken">Dieser Benutzername ist bereits vergeben.</string>
|
<string name="signup_username_taken">Dieser Benutzername ist bereits vergeben.</string>
|
||||||
|
<string name="spoiler_show">Trotzdem anzeigen</string>
|
||||||
|
<string name="spoiler_hide">Wieder verstecken</string>
|
||||||
|
<string name="poll_multiple_choice">Wähle ein/e oder mehrere aus</string>
|
||||||
|
<string name="save_changes">Änderungen speichern</string>
|
||||||
|
<string name="profile_featured">Empfohlen</string>
|
||||||
|
<string name="profile_timeline">Timeline</string>
|
||||||
|
<string name="view_all">Alle anzeigen</string>
|
||||||
|
<string name="profile_endorsed_accounts">Konten</string>
|
||||||
|
<string name="verified_link">Verifizierter Link</string>
|
||||||
|
<string name="show">Anzeigen</string>
|
||||||
|
<string name="hide">Ausblenden</string>
|
||||||
|
<string name="join_default_server">%s beitreten</string>
|
||||||
|
<string name="signup_or_login">oder</string>
|
||||||
|
<string name="learn_more">Mehr erfahren</string>
|
||||||
|
<string name="welcome_to_mastodon">Willkommen auf Mastodon</string>
|
||||||
|
<string name="what_are_servers">Was sind Server?</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<string name="sk_poll_allow_multiple">Mehrfachantworten erlauben</string>
|
<string name="sk_poll_allow_multiple">Mehrfachantworten erlauben</string>
|
||||||
<string name="sk_translated_using">Übersetzt mit %s</string>
|
<string name="sk_translated_using">Übersetzt mit %s</string>
|
||||||
<string name="sk_post_language">Sprache: %s</string>
|
<string name="sk_post_language">Sprache: %s</string>
|
||||||
<string name="sk_language_name">%s (%s)</string>
|
<string name="sk_language_name">%1$s (%2$s)</string>
|
||||||
<string name="sk_confirm_clear_recent_languages">Sicher, dass du die Liste der zuletzt verwendeten Sprachen leeren willst\?</string>
|
<string name="sk_confirm_clear_recent_languages">Sicher, dass du die Liste der zuletzt verwendeten Sprachen leeren willst\?</string>
|
||||||
<string name="sk_translate_post">Übersetzen</string>
|
<string name="sk_translate_post">Übersetzen</string>
|
||||||
<string name="sk_translate_show_original">Original anzeigen</string>
|
<string name="sk_translate_show_original">Original anzeigen</string>
|
||||||
@@ -82,8 +82,8 @@
|
|||||||
<string name="sk_settings_translation_availability_note_available">%s unterstützt Übersetzung!</string>
|
<string name="sk_settings_translation_availability_note_available">%s unterstützt Übersetzung!</string>
|
||||||
<string name="sk_settings_translation_availability_note_unavailable">%s scheint keine Übersetzung zu unterstützen.</string>
|
<string name="sk_settings_translation_availability_note_unavailable">%s scheint keine Übersetzung zu unterstützen.</string>
|
||||||
<string name="sk_loading_fediverse_resource_title">Suche im Fediverse</string>
|
<string name="sk_loading_fediverse_resource_title">Suche im Fediverse</string>
|
||||||
<string name="sk_undo_reblog">Reblog rückgängig machen</string>
|
<string name="sk_undo_reblog">Teilen rückgängig machen</string>
|
||||||
<string name="sk_reblog_with_visibility">Rebloggen mit Sichtbarkeit</string>
|
<string name="sk_reblog_with_visibility">Teilen mit Sichtbarkeit</string>
|
||||||
<string name="sk_quote_post">Drüberkommentieren</string>
|
<string name="sk_quote_post">Drüberkommentieren</string>
|
||||||
<string name="sk_hashtags_you_follow">Hashtags, denen du folgst</string>
|
<string name="sk_hashtags_you_follow">Hashtags, denen du folgst</string>
|
||||||
<string name="sk_copy_link_to_post">Link zum Beitrag kopieren</string>
|
<string name="sk_copy_link_to_post">Link zum Beitrag kopieren</string>
|
||||||
@@ -96,9 +96,9 @@
|
|||||||
<string name="sk_favorite_as">Favorit mit anderem Konto</string>
|
<string name="sk_favorite_as">Favorit mit anderem Konto</string>
|
||||||
<string name="sk_favorited_as">Favorisiert als %s</string>
|
<string name="sk_favorited_as">Favorisiert als %s</string>
|
||||||
<string name="sk_already_favorited">Bereits favorisiert</string>
|
<string name="sk_already_favorited">Bereits favorisiert</string>
|
||||||
<string name="sk_reblog_as">Mit einem anderen Konto boosten</string>
|
<string name="sk_reblog_as">Mit einem anderen Konto teilen</string>
|
||||||
<string name="sk_reblogged_as">Geboostet als %s</string>
|
<string name="sk_reblogged_as">Geteilt als %s</string>
|
||||||
<string name="sk_already_reblogged">Bereits geboostet</string>
|
<string name="sk_already_reblogged">Bereits geteilt</string>
|
||||||
<string name="sk_reply_as">Antworten mit anderem Konto</string>
|
<string name="sk_reply_as">Antworten mit anderem Konto</string>
|
||||||
<string name="sk_settings_uniform_icon_for_notifications">Einheitliches Icon für alle Benachrichtigungen</string>
|
<string name="sk_settings_uniform_icon_for_notifications">Einheitliches Icon für alle Benachrichtigungen</string>
|
||||||
<string name="sk_forward_report_to">Weiterleiten zu %s</string>
|
<string name="sk_forward_report_to">Weiterleiten zu %s</string>
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
<string name="sk_alt_text_missing_title">Fehlende Bildbeschreibung</string>
|
<string name="sk_alt_text_missing_title">Fehlende Bildbeschreibung</string>
|
||||||
<string name="sk_settings_disable_alt_text_reminder">Erinnerung zum Hinzufügen von Bildbeschreibungen ausschalten</string>
|
<string name="sk_settings_disable_alt_text_reminder">Erinnerung zum Hinzufügen von Bildbeschreibungen ausschalten</string>
|
||||||
<string name="sk_alt_button">ALT</string>
|
<string name="sk_alt_button">ALT</string>
|
||||||
<string name="sk_notify_update">Bearbeitet einen geteilten Beitrag</string>
|
<string name="sk_notify_update">einen geteilten Beitrag bearbeitet</string>
|
||||||
<string name="sk_timelines">Timelines</string>
|
<string name="sk_timelines">Timelines</string>
|
||||||
<string name="sk_timeline">Timeline</string>
|
<string name="sk_timeline">Timeline</string>
|
||||||
<string name="sk_hashtag">Hashtag</string>
|
<string name="sk_hashtag">Hashtag</string>
|
||||||
@@ -269,6 +269,9 @@
|
|||||||
<string name="sk_quoting_user">Zitiere %s</string>
|
<string name="sk_quoting_user">Zitiere %s</string>
|
||||||
<string name="sk_notification_action_replied">Antwort an %s gesendet</string>
|
<string name="sk_notification_action_replied">Antwort an %s gesendet</string>
|
||||||
<string name="sk_show_thread">Thread öffnen</string>
|
<string name="sk_show_thread">Thread öffnen</string>
|
||||||
<string name="sk_compact_reblog_reply_line">Kompakte Geteilt/Geantwortet-Zeile</string>
|
<string name="sk_compact_reblog_reply_line">Kompakte Geteilt-/Geantwortet-Zeile</string>
|
||||||
<string name="sk_reply_line_above_avatar">“Als Antwort auf”-Zeile über Profilbild</string>
|
<string name="sk_reply_line_above_avatar">“Als Antwort auf”-Zeile über Profilbild</string>
|
||||||
|
<string name="sk_settings_confirm_before_reblog">Vor dem Teilen bestätigen</string>
|
||||||
|
<string name="sk_reacted">hat reagiert</string>
|
||||||
|
<string name="sk_reacted_with">hat mit %s reagiert</string>
|
||||||
</resources>
|
</resources>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user