Compare commits

..
Author SHA1 Message Date
txyyh 428ae07e7f Release 1.8.5.0
Releases / Build (push) Has been cancelled
2022-12-19 14:59:35 +00:00
tarsin 481ad22b53 Code cleanup 2022-12-19 13:00:06 +08:00
FooIbar 65f58b93ed Update mCurrentIndex on page move
Resolve #538
2022-12-19 12:09:31 +08:00
FooIbar 45411fa14d Use notifyAll() instead of notify() on mDecodeRequestQueue
Resolve #549
2022-12-19 08:13:31 +08:00
tarsin 8ba1ba4fb1 fixup! Minor Refactor 2022-12-18 14:06:55 +08:00
tarsin 8427e1b3a5 fixup! Minor Refactor 2022-12-18 13:55:16 +08:00
tarsin 32f0f2a0cf Fix isTranslatable 2022-12-18 13:02:12 +08:00
tarsin 8b94997cde Minor Refactor 2022-12-18 12:52:30 +08:00
tarsin bd2d54f774 fixup! Rewrite search suggestion with kotlin flow, remove suggestion limit 2022-12-18 11:31:49 +08:00
FooIbar 34be285510 Do not add neighbors on page success
Might resolve #536 #540
2022-12-18 09:13:38 +08:00
FooIbar 7b906f3c3e Update tag database format 2022-12-18 07:55:37 +08:00
tarsin 82ba22cda2 Resolve #542 2022-12-17 14:24:24 +08:00
tarsin b1a9601ae9 fixup! Rewrite search suggestion with kotlin flow, remove suggestion limit 2022-12-17 13:08:08 +08:00
tarsin 7c1a297a99 Remove unused shared libs 2022-12-17 12:59:02 +08:00
FooIbar a8195c0e7c Map archive index with filename order
Try to resolve #427
2022-12-17 12:53:13 +08:00
FooIbar 08713e3922 Use SummaryProvider instead of String formatting marker 2022-12-17 12:53:13 +08:00
tarsin 0485d52e3e Rewrite search suggestion with kotlin flow, remove suggestion limit 2022-12-17 12:47:37 +08:00
tarsin 8b1723e19b Rename .java to .kt 2022-12-17 12:47:37 +08:00
tarsin 9cb683dc55 Fix crash when zoomed and try to swipe to next page 2022-12-16 22:07:09 +08:00
tarsin dce1589c19 Fix remaining request not cancelled for detached image 2022-12-16 21:35:28 +08:00
FooIbar 107cf16d36 Remove unused maven repo due to a677d95 2022-12-16 03:50:35 +08:00
FooIbar 2bab97c829 Better way to handle tag translation flag 2022-12-16 03:50:35 +08:00
tarsin 5242d825c2 Change location 2022-12-15 11:43:42 +08:00
FooIbar 11d3799b03 Change tag database format to json for better maintainability 2022-12-15 11:38:32 +08:00
FooIbar 55c7f6b896 Support tag suggestion for all languages 2022-12-15 06:43:50 +08:00
tarsin a09d607177 Do colorspace trans if needed 2022-12-14 17:24:19 +08:00
txyyh 626a101208 Rename Repository 2022-12-14 07:39:04 +00:00
tarsin f4ca3acbf6 Fix statusbar 2022-12-14 14:32:40 +08:00
tarsin 86835a3bd7 Remove toolbar and fix theme 2022-12-14 14:26:15 +08:00
tarsin 0ef46e2e11 Move image blobs to another repo 2022-12-14 12:24:17 +08:00
tarsin 04878447b7 Fixup translation import 2022-12-14 12:07:35 +08:00
tarsin 3669d5d90e Resolve #527 2022-12-14 11:25:06 +08:00
tarsin ee5e222a13 Resolve #525 2022-12-14 11:11:20 +08:00
tarsin 9ea44ff59a Remove blur when adjust color filter 2022-12-14 10:58:32 +08:00
tarsin 0474e2c0f5 Kill read settings in preference, clean up res 2022-12-14 10:39:06 +08:00
tarsin 4a909d4b93 Support readWithVolumeKeys 2022-12-14 10:32:46 +08:00
70 changed files with 601 additions and 1879 deletions

No files matched your search

+4 -4
View File
@@ -11,7 +11,7 @@
</p>
<h1 align="center">
<img src="art/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<br>EhViewer<br>
</h1>
@@ -66,12 +66,12 @@ with Material Design 3 and Dynamic Color Support
# Download
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="art/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="art/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
# Screenshot
![screenshot-01](art/screenshot-01.png)
![screenshot-02](art/screenshot-02.png)
![screenshot-01](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-01.png)
![screenshot-02](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-02.png)
# Thanks
+2 -2
View File
@@ -31,8 +31,8 @@ android {
applicationId "moe.tarsin.ehviewer"
minSdkVersion 28
targetSdkVersion 33
versionCode 180027
versionName "1.8.5.0-preview"
versionCode 180028
versionName "1.8.5.0"
resConfigs 'zh', 'zh-rCN', 'zh-rHK', 'zh-rTW', 'es', 'ja', 'ko', 'fr', 'de', 'th'
}
-4
View File
@@ -32,10 +32,6 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:name="com.hippo.ehviewer.EhApplication"
android:allowBackup="true"
+1 -1
View File
@@ -47,4 +47,4 @@ add_subdirectory(libarchive)
# Build and link our app's native lib
add_library(${PROJECT_NAME} SHARED archive.c fdutils.c)
target_include_directories(${PROJECT_NAME} PUBLIC libarchive/libarchive)
target_link_libraries(${PROJECT_NAME} archive_static log jnigraphics GLESv2 -Wl,--gc-sections)
target_link_libraries(${PROJECT_NAME} archive_static log -Wl,--gc-sections)
+53 -2
View File
@@ -43,6 +43,11 @@ typedef struct {
struct archive_entry *entry;
} archive_ctx;
typedef struct {
const char *filename;
int index;
} entry;
pthread_mutex_t ctx_lock;
static archive_ctx **ctx_pool;
#define CTX_POOL_SIZE 20
@@ -51,6 +56,8 @@ static bool need_encrypt = false;
static char *passwd = NULL;
static void *archiveAddr = NULL;
static size_t archiveSize = 0;
static entry *entries = NULL;
static size_t entryCount = 0;
#define POPULATE_THRESHOLD (512 * 1024 * 1024) // 512 MiB
@@ -77,6 +84,30 @@ static inline int filename_is_playable_file(const char *name) {
return false;
}
static inline int compare_entries(const void *a, const void *b) {
const char *fa = ((entry *) a)->filename;
const char *fb = ((entry *) b)->filename;
int a_len = (int) strlen(fa);
int b_len = (int) strlen(fb);
return a_len == b_len ? strcmp(fa, fb) : a_len - b_len;
}
static long archive_map_entries_index(archive_ctx *ctx) {
long count = 0;
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK) {
const char *name = archive_entry_pathname(ctx->entry);
if (filename_is_playable_file(name)) {
entries[count].filename = strdup(name);
entries[count].index = count;
count++;
}
}
if (!count)
LOGE("%s", archive_error_string(ctx->arc));
qsort(entries, entryCount, sizeof(entry), compare_entries);
return count;
}
static long archive_list_all_entries(archive_ctx *ctx) {
long count = 0;
while (archive_read_next_header(ctx->arc, &ctx->entry) == ARCHIVE_OK)
@@ -221,10 +252,9 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd
if (r) {
if (r == -ENOMEM)
LOGE("%s", "Mem alloc failed");
r = 0;
LOGE("%s%s", "Archive open failed:", archive_error_string(ctx->arc));
} else {
r = archive_list_all_entries(ctx);
entryCount = archive_list_all_entries(ctx);
LOGI("%s%ld%s", "Found ", r, " image entries in archive");
// We must read through the file|vm then we can know whether it is encrypted
@@ -251,6 +281,19 @@ Java_com_hippo_UriArchiveAccessor_openArchive(JNIEnv *env, jobject thiz, jint fd
}
}
archive_release_ctx(ctx);
r = archive_alloc_ctx(&ctx);
if (r) {
if (r == -ENOMEM)
LOGE("%s", "Mem alloc failed");
r = 0;
LOGE("%s%s", "Archive open failed:", archive_error_string(ctx->arc));
} else {
entries = calloc(entryCount, sizeof(entry));
r = archive_map_entries_index(ctx);
}
archive_release_ctx(ctx);
return r;
}
@@ -259,6 +302,7 @@ JNIEXPORT jobject JNICALL
Java_com_hippo_UriArchiveAccessor_extractToByteBuffer(JNIEnv *env, jobject thiz, jint index) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
archive_ctx *ctx = NULL;
int ret;
ret = archive_get_ctx(&ctx, index);
@@ -295,6 +339,10 @@ Java_com_hippo_UriArchiveAccessor_closeArchive(JNIEnv *env, jobject thiz) {
passwd = NULL;
need_encrypt = false;
munmap(archiveAddr, archiveSize);
for (int i = 0; i < entryCount; ++i) {
free((void *) entries[i].filename);
}
free(entries);
}
JNIEXPORT jboolean JNICALL
@@ -338,6 +386,7 @@ JNIEXPORT jstring JNICALL
Java_com_hippo_UriArchiveAccessor_getFilename(JNIEnv *env, jobject thiz, jint index) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
archive_ctx *ctx = NULL;
int ret;
ret = archive_get_ctx(&ctx, index);
@@ -352,6 +401,7 @@ JNIEXPORT void JNICALL
Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint index, jint fd) {
EH_UNUSED(env);
EH_UNUSED(thiz);
index = entries[index].index;
archive_ctx *ctx = NULL;
int ret;
ret = archive_get_ctx(&ctx, index);
@@ -363,6 +413,7 @@ Java_com_hippo_UriArchiveAccessor_extractToFd(JNIEnv *env, jobject thiz, jint in
JNIEXPORT void JNICALL
Java_com_hippo_UriArchiveAccessor_releaseByteBuffer(JNIEnv *env, jobject thiz, jobject buffer) {
EH_UNUSED(thiz);
void *addr = (*env)->GetDirectBufferAddress(env, buffer);
free(addr);
}
@@ -476,8 +476,10 @@ open class SubsamplingScaleImageView @JvmOverloads constructor(
private fun setGestureDetector(context: Context) {
detector = GestureDetector(context, object : GestureDetector.SimpleOnGestureListener() {
@Suppress("SENSELESS_COMPARISON")
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
if (panEnabled && isReady && vTranslate != null && (abs(e1.x - e2.x) > 50 || abs(e1.y - e2.y) > 50) && (abs(velocityX) > 500 || abs(velocityY) > 500) && !isZooming) {
// The e1 can be null, that's weird and cause crash
if (panEnabled && isReady && vTranslate != null && e1 != null && e2 != null && (abs(e1.x - e2.x) > 50 || abs(e1.y - e2.y) > 50) && (abs(velocityX) > 500 || abs(velocityY) > 500) && !isZooming) {
val vTranslateEnd = PointF(vTranslate!!.x + velocityX * 0.25F, vTranslate!!.y + velocityY * 0.25F)
val sCenterXEnd = (width / 2 - vTranslateEnd.x) / scale
val sCenterYEnd = (height / 2 - vTranslateEnd.y) / scale
@@ -23,6 +23,7 @@ import androidx.annotation.Nullable;
import com.hippo.streampipe.InputStreamPipe;
import com.hippo.streampipe.OutputStreamPipe;
import com.hippo.util.HashCodeUtils;
import java.io.File;
import java.io.IOException;
@@ -85,32 +86,13 @@ public class SimpleDiskCache {
try {
final MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(key.getBytes());
cacheKey = bytesToHexString(digest.digest());
cacheKey = HashCodeUtils.bytesToHexString(digest.digest());
} catch (final NoSuchAlgorithmException e) {
cacheKey = String.valueOf(key.hashCode());
}
return cacheKey;
}
/**
* http://stackoverflow.com/questions/332079
*
* @param bytes The bytes to convert.
* @return A {@link String} converted from the bytes of a hashable key used
* to store a filename on the disk, to hex digits.
*/
private static String bytesToHexString(final byte[] bytes) {
final StringBuilder builder = new StringBuilder();
for (final byte b : bytes) {
final String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
builder.append('0');
}
builder.append(hex);
}
return builder.toString();
}
public synchronized boolean isValid() {
return mDiskLruCache != null;
}
@@ -1,176 +0,0 @@
/*
* Copyright (C) 2014 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.drawable;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import com.hippo.yorozuya.MathUtils;
public class BatteryDrawable extends Drawable {
public static final int WARN_LIMIT = 15;
@SuppressWarnings("unused")
private static final String TAG = BatteryDrawable.class.getSimpleName();
private final Paint mPaint;
private final Rect mTopRect;
private final Rect mBottomRect;
private final Rect mRightRect;
private final Rect mHeadRect;
private final Rect mElectRect;
private int mColor = Color.WHITE;
private int mWarningColor = Color.RED;
private int mElect = -1;
private int mStart;
private int mStop;
public BatteryDrawable() {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
mPaint.setStyle(Paint.Style.FILL);
mTopRect = new Rect();
mBottomRect = new Rect();
mRightRect = new Rect();
mHeadRect = new Rect();
mElectRect = new Rect();
updatePaint();
}
@Override
@SuppressWarnings("SuspiciousNameCombination")
protected void onBoundsChange(Rect bounds) {
int width = bounds.width();
int height = bounds.height();
int strokeWidth = (int) (Math.sqrt(width * width + height * height) * 0.06f);
int turn1 = width * 6 / 7;
int turn2 = height / 3;
int secBottom = height - strokeWidth;
mStart = strokeWidth;
mStop = turn1 - strokeWidth;
mTopRect.set(0, 0, turn1, strokeWidth);
mBottomRect.set(0, secBottom, turn1, height);
mRightRect.set(turn1 - strokeWidth, strokeWidth, turn1, secBottom);
mHeadRect.set(turn1, turn2, width, height - turn2);
mElectRect.set(0, strokeWidth, mStop, secBottom);
}
/**
* How to draw:<br>
* |------------------------------|<br>
* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|<br>
* |------------------------------|---|<br>
* |/////////////////| |//|\\\|<br>
* |/////////////////| |//|\\\|<br>
* |------------------------------|---|<br>
* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\|<br>
* |------------------------------|
*/
@Override
public void draw(Canvas canvas) {
if (mElect == -1) {
return;
}
mElectRect.right = MathUtils.lerp(mStart, mStop, mElect / 100.0f);
canvas.drawRect(mTopRect, mPaint);
canvas.drawRect(mBottomRect, mPaint);
canvas.drawRect(mRightRect, mPaint);
canvas.drawRect(mHeadRect, mPaint);
canvas.drawRect(mElectRect, mPaint);
}
private boolean isWarn() {
return mElect <= WARN_LIMIT;
}
public void setColor(int color) {
if (mColor == color) {
return;
}
mColor = color;
if (!isWarn()) {
mPaint.setColor(mColor);
invalidateSelf();
}
}
public void setWarningColor(int color) {
if (mWarningColor == color) {
return;
}
mWarningColor = color;
if (isWarn()) {
mPaint.setColor(mWarningColor);
invalidateSelf();
}
}
public void setElect(int elect) {
if (mElect == elect) {
return;
}
mElect = elect;
updatePaint();
}
public void setElect(int elect, boolean warn) {
if (mElect == elect) {
return;
}
mElect = elect;
updatePaint(warn);
}
private void updatePaint() {
updatePaint(isWarn());
}
private void updatePaint(boolean warn) {
if (warn) {
mPaint.setColor(mWarningColor);
} else {
mPaint.setColor(mColor);
}
invalidateSelf();
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
}
@Override
public void setColorFilter(ColorFilter cf) {
mPaint.setColorFilter(cf);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
@@ -43,6 +43,7 @@ import com.hippo.ehviewer.client.EhDns
import com.hippo.ehviewer.client.EhEngine
import com.hippo.ehviewer.client.EhRequestBuilder
import com.hippo.ehviewer.client.EhSSLSocketFactory
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.client.EhUrl
import com.hippo.ehviewer.client.EhX509TrustManager
import com.hippo.ehviewer.client.data.GalleryDetail
@@ -77,7 +78,6 @@ class EhApplication : SceneApplication(), DefaultLifecycleObserver, ImageLoaderF
private val mIdGenerator = IntIdGenerator()
private val mGlobalStuffMap = HashMap<Int, Any>()
private val mActivityList = ArrayList<Activity>()
private var initialized = false
val topActivity: EhActivity?
get() = if (mActivityList.isNotEmpty()) {
mActivityList[mActivityList.size - 1] as EhActivity
@@ -114,6 +114,7 @@ class EhApplication : SceneApplication(), DefaultLifecycleObserver, ImageLoaderF
EhDB.initialize(this)
EhEngine.initialize()
BitmapUtils.initialize(this)
EhTagDatabase.update()
// Locales can be managed by system automatically above Snow Cone v2
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU)
@@ -147,7 +148,6 @@ class EhApplication : SceneApplication(), DefaultLifecycleObserver, ImageLoaderF
theDawnOfNewDay()
}
mIdGenerator.setNextId(Settings.getInt(KEY_GLOBAL_STUFF_NEXT_ID, 0))
initialized = true
}
private suspend fun theDawnOfNewDay() {
@@ -296,7 +296,7 @@ class EhApplication : SceneApplication(), DefaultLifecycleObserver, ImageLoaderF
val builder = OkHttpClient.Builder()
.cookieJar(ehCookieStore)
.cache(Cache(File(application.cacheDir, "http_cache"), 50L * 1024L * 1024L))
.dns(EhDns())
.dns(EhDns)
.proxySelector(ehProxySelector)
if (Settings.getDF()) {
@@ -315,10 +315,10 @@ class EhApplication : SceneApplication(), DefaultLifecycleObserver, ImageLoaderF
trustManager = trustManagers[0] as X509TrustManager
} catch (e: Exception) {
e.printStackTrace()
trustManager = EhX509TrustManager()
trustManager = EhX509TrustManager
}
builder.sslSocketFactory(EhSSLSocketFactory(), trustManager)
builder.sslSocketFactory(EhSSLSocketFactory, trustManager)
builder.proxy(Proxy.NO_PROXY)
}
builder.build()
@@ -27,6 +27,7 @@ import androidx.annotation.Nullable;
import androidx.preference.PreferenceManager;
import com.hippo.ehviewer.client.EhConfig;
import com.hippo.ehviewer.client.EhTagDatabase;
import com.hippo.ehviewer.client.data.FavListUrlBuilder;
import com.hippo.ehviewer.ui.CommonOperations;
import com.hippo.ehviewer.ui.scene.GalleryListScene;
@@ -460,7 +461,7 @@ public class Settings {
}
public static boolean getShowTagTranslations() {
return getBoolean(KEY_SHOW_TAG_TRANSLATIONS, DEFAULT_SHOW_TAG_TRANSLATIONS);
return getBoolean(KEY_SHOW_TAG_TRANSLATIONS, DEFAULT_SHOW_TAG_TRANSLATIONS) && EhTagDatabase.INSTANCE.isTranslatable();
}
public static void putShowTagTranslations(boolean value) {
@@ -22,7 +22,7 @@ import okhttp3.Dns
import java.net.InetAddress
import java.net.UnknownHostException
class EhDns : Dns {
object EhDns : Dns {
private val hosts = EhApplication.hosts
private val builtInHosts: MutableMap<String, List<InetAddress>> = mutableMapOf()
@@ -23,7 +23,7 @@ import java.net.Socket
import javax.net.ssl.SSLSocket
import javax.net.ssl.SSLSocketFactory
class EhSSLSocketFactory : SSLSocketFactory() {
object EhSSLSocketFactory : SSLSocketFactory() {
private val sslSocketFactory = getDefault() as SSLSocketFactory
override fun getDefaultCipherSuites(): Array<String> {
return sslSocketFactory.defaultCipherSuites
@@ -1,436 +0,0 @@
/*
* Copyright 2019 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.client;
import android.content.Context;
import android.util.Base64;
import androidx.annotation.Nullable;
import androidx.core.util.Pair;
import com.hippo.ehviewer.AppConfig;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.util.ExceptionUtils;
import com.hippo.util.IoThreadPoolExecutor;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.BufferedSource;
import okio.Okio;
public class EhTagDatabase {
private static final Map<String, String> NAMESPACE_TO_PREFIX = new HashMap<>();
// TODO more lock for different language
private static final Lock lock = new ReentrantLock();
private static volatile EhTagDatabase instance;
static {
NAMESPACE_TO_PREFIX.put("artist", "a:");
NAMESPACE_TO_PREFIX.put("cosplayer", "cos:");
NAMESPACE_TO_PREFIX.put("character", "c:");
NAMESPACE_TO_PREFIX.put("female", "f:");
NAMESPACE_TO_PREFIX.put("group", "g:");
NAMESPACE_TO_PREFIX.put("language", "l:");
NAMESPACE_TO_PREFIX.put("male", "m:");
NAMESPACE_TO_PREFIX.put("mixed", "x:");
NAMESPACE_TO_PREFIX.put("other", "o:");
NAMESPACE_TO_PREFIX.put("parody", "p:");
NAMESPACE_TO_PREFIX.put("reclass", "r:");
}
private final String name;
private final byte[] tags;
public EhTagDatabase(String name, BufferedSource source) throws IOException {
this.name = name;
String[] tmp;
StringBuilder buffer = new StringBuilder();
source.readInt();
for (String i : source.readUtf8().split("\n")) {
tmp = i.split("\r", 2);
buffer.append(tmp[0]);
buffer.append("\r");
try {
buffer.append(new String(Base64.decode(tmp[1], Base64.DEFAULT), StandardCharsets.UTF_8));
} catch (Exception e) {
buffer.append(tmp[1]);
}
buffer.append("\n");
}
byte[] b = buffer.toString().getBytes(StandardCharsets.UTF_8);
int totalBytes = b.length;
tags = new byte[totalBytes];
System.arraycopy(b, 0, tags, 0, totalBytes);
}
@Nullable
public static EhTagDatabase getInstance(Context context) {
if (isPossible(context)) {
return instance;
} else {
instance = null;
return null;
}
}
@Nullable
public static String namespaceToPrefix(String namespace) {
return NAMESPACE_TO_PREFIX.get(namespace);
}
private static String[] getMetadata(Context context) {
String[] metadata = context.getResources().getStringArray(R.array.tag_translation_metadata);
if (metadata.length == 4) {
return metadata;
} else {
return null;
}
}
public static boolean isPossible(Context context) {
return getMetadata(context) != null;
}
@Nullable
private static byte[] getFileContent(File file, int length) {
try (BufferedSource source = Okio.buffer(Okio.source(file))) {
byte[] content = new byte[length];
source.readFully(content);
return content;
} catch (IOException e) {
return null;
}
}
@Nullable
private static byte[] getFileSha1(File file) {
try (InputStream is = new FileInputStream(file)) {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
int n;
byte[] buffer = new byte[4 * 1024];
while ((n = is.read(buffer)) != -1) {
digest.update(buffer, 0, n);
}
return digest.digest();
} catch (IOException | NoSuchAlgorithmException e) {
return null;
}
}
private static boolean equals(byte[] b1, byte[] b2) {
if (b1 == null && b2 == null) {
return true;
}
if (b1 == null || b2 == null) {
return false;
}
if (b1.length != b2.length) {
return false;
}
for (int i = 0; i < b1.length; i++) {
if (b1[i] != b2[i]) {
return false;
}
}
return true;
}
private static boolean checkData(File sha1File, File dataFile) {
byte[] s1 = getFileContent(sha1File, 20);
if (s1 == null) {
return false;
}
byte[] s2 = getFileSha1(dataFile);
if (s2 == null) {
return false;
}
return equals(s1, s2);
}
private static boolean save(OkHttpClient client, String url, File file) {
Request request = new Request.Builder().url(url).build();
Call call = client.newCall(request);
try (Response response = call.execute()) {
if (!response.isSuccessful()) {
return false;
}
ResponseBody body = response.body();
if (body == null) {
return false;
}
try (InputStream is = body.byteStream(); OutputStream os = new FileOutputStream(file)) {
IOUtils.copy(is, os);
}
return true;
} catch (Throwable t) {
t.printStackTrace();
ExceptionUtils.throwIfFatal(t);
return false;
}
}
public static void update(Context context) {
String[] urls = getMetadata(context);
if (urls == null || urls.length != 4) {
// Clear tags if it's not possible
instance = null;
return;
}
String sha1Name = urls[0];
String sha1Url = urls[1];
String dataName = urls[2];
String dataUrl = urls[3];
// Clear tags if name if different
EhTagDatabase tmp = instance;
if (tmp != null && !tmp.name.equals(dataName)) {
instance = null;
}
IoThreadPoolExecutor.getInstance().execute(() -> {
if (!lock.tryLock()) {
return;
}
try {
File dir = AppConfig.getFilesDir("tag-translations");
if (dir == null) {
return;
}
// Check current sha1 and current data
File sha1File = new File(dir, sha1Name);
File dataFile = new File(dir, dataName);
if (!checkData(sha1File, dataFile)) {
FileUtils.delete(sha1File);
FileUtils.delete(dataFile);
}
// Read current EhTagDatabase
if (instance == null && dataFile.exists()) {
try (BufferedSource source = Okio.buffer(Okio.source(dataFile))) {
instance = new EhTagDatabase(dataName, source);
} catch (IOException e) {
FileUtils.delete(sha1File);
FileUtils.delete(dataFile);
}
}
OkHttpClient client = EhApplication.getOkHttpClient();
// Save new sha1
File tempSha1File = new File(dir, sha1Name + ".tmp");
if (!save(client, sha1Url, tempSha1File)) {
FileUtils.delete(tempSha1File);
return;
}
// Check new sha1 and current data
if (checkData(tempSha1File, dataFile)) {
// The data is the same
FileUtils.delete(tempSha1File);
return;
}
// Save new data
File tempDataFile = new File(dir, dataName + ".tmp");
if (!save(client, dataUrl, tempDataFile)) {
FileUtils.delete(tempDataFile);
return;
}
// Check new sha1 and new data
if (!checkData(tempSha1File, tempDataFile)) {
FileUtils.delete(tempSha1File);
FileUtils.delete(tempDataFile);
return;
}
// Replace current sha1 and current data with new sha1 and new data
FileUtils.delete(sha1File);
FileUtils.delete(dataFile);
tempSha1File.renameTo(sha1File);
tempDataFile.renameTo(dataFile);
// Read new EhTagDatabase
try (BufferedSource source = Okio.buffer(Okio.source(dataFile))) {
instance = new EhTagDatabase(dataName, source);
} catch (IOException e) {
// Ignore
}
} finally {
lock.unlock();
}
});
}
public String getTranslation(String tag) {
return search(tags, tag.getBytes(StandardCharsets.UTF_8));
}
@Nullable
private String search(byte[] tags, byte[] tag) {
int low = 0;
int high = tags.length;
while (low < high) {
int start = (low + high) / 2;
// Look for the starting '\n'
while (start > -1 && tags[start] != '\n') {
start--;
}
start++;
// Look for the middle '\r'.
int middle = 1;
while (tags[start + middle] != '\r') {
middle++;
}
// Look for the ending '\n'
int end = middle + 1;
while (tags[start + end] != '\n') {
end++;
}
int compare;
int tagIndex = 0;
int curIndex = start;
for (; ; ) {
int tagByte = tag[tagIndex] & 0xff;
int curByte = tags[curIndex] & 0xff;
compare = tagByte - curByte;
if (compare != 0) {
break;
}
tagIndex++;
curIndex++;
if (tagIndex == tag.length && curIndex == start + middle) {
break;
}
if (tagIndex == tag.length) {
compare = -1;
break;
}
if (curIndex == start + middle) {
compare = 1;
break;
}
}
if (compare < 0) {
high = start - 1;
} else if (compare > 0) {
low = start + end + 1;
} else {
return new String(tags, start + middle + 1, end - middle - 1, StandardCharsets.UTF_8);
}
}
return null;
}
public ArrayList<Pair<String, String>> suggest(String keyword) {
return searchTag(tags, keyword);
}
private ArrayList<Pair<String, String>> searchTag(byte[] tags, String keyword) {
ArrayList<Pair<String, String>> searchHints = new ArrayList<>();
int begin = 0;
while (begin < tags.length - 1) {
int start = begin;
// Look for the starting '\n'
while (tags[start] != '\n') {
start++;
}
// Look for the middle '\r'.
int middle = 1;
while (tags[start + middle] != '\r') {
middle++;
}
// Look for the ending '\n'
int end = middle + 1;
while (tags[start + end] != '\n') {
end++;
}
begin = start + end;
byte[] hintBytes = new byte[end - middle - 1];
System.arraycopy(tags, start + middle + 1, hintBytes, 0, end - middle - 1);
String hint = new String(hintBytes, StandardCharsets.UTF_8);
byte[] tagBytes = new byte[middle];
System.arraycopy(tags, start + 1, tagBytes, 0, middle);
String tag = new String(tagBytes, StandardCharsets.UTF_8);
int index = tag.indexOf(':');
boolean keywordMatches;
if (index == -1 || index >= tag.length() - 1 || keyword.length() > 2) {
keywordMatches = containsIgnoreSpace(tag, keyword);
} else {
keywordMatches = containsIgnoreSpace(tag.substring(index + 1), keyword);
}
if (keywordMatches || containsIgnoreSpace(hint, keyword)) {
Pair<String, String> pair = new Pair<>(hint, tag);
if (!searchHints.contains(pair)) {
searchHints.add(pair);
}
}
if (searchHints.size() > 20) {
break;
}
}
return searchHints;
}
private boolean containsIgnoreSpace(String text, String key) {
return text.replace(" ", "").contains(key.replace(" ", ""));
}
}
@@ -0,0 +1,271 @@
/*
* Copyright 2019 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.client
import android.content.Context
import com.hippo.ehviewer.AppConfig
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.EhApplication.Companion.okHttpClient
import com.hippo.ehviewer.R
import com.hippo.util.ExceptionUtils
import com.hippo.util.HashCodeUtils
import com.hippo.yorozuya.FileUtils
import com.hippo.yorozuya.IOUtils
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import okhttp3.OkHttpClient
import okhttp3.Request
import okio.BufferedSource
import okio.buffer
import okio.source
import org.json.JSONException
import org.json.JSONObject
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
object EhTagDatabase {
private lateinit var tags: JSONObject
private lateinit var tagList: ArrayList<Pair<String, String>>
fun isInitialized(): Boolean {
return this::tags.isInitialized && this::tagList.isInitialized
}
private fun updateData(source: BufferedSource) {
try {
val tmpTags = JSONObject(source.readString(StandardCharsets.UTF_8))
val tmpTagList = arrayListOf<Pair<String, String>>()
tmpTags.keys().forEachRemaining { prefix: String ->
val values = tmpTags.optJSONObject(prefix)
values?.let {
it.keys().forEachRemaining { tag: String ->
tmpTagList.add(Pair("$prefix:$tag", values.optString(tag)))
}
}
}
tags = tmpTags
tagList = tmpTagList
} catch (e: JSONException) {
e.printStackTrace()
}
}
fun getTranslation(prefix: String?, tag: String?): String? {
return tags.optJSONObject(prefix)?.optString(tag)?.trim()?.takeIf { it.isNotEmpty() }
}
/* Construct a cold flow for tag database suggestions */
fun suggestFlow(
keyword: String,
translate: Boolean,
exactly: Boolean = false
): Flow<Pair<String?, String>> = flow {
tagList.forEach {
val tag = it.first
val hint = if (translate) it.second else null
val index = tag.indexOf(':')
if (tag.substring(index + 1).trim() == keyword) {
if (exactly)
emit(Pair(hint, tag))
return@forEach
}
if (exactly)
return@forEach
val keywordMatches: Boolean =
if (index == -1 || index >= tag.length - 1 || keyword.length > 2) {
containsIgnoreSpace(tag, keyword)
} else {
containsIgnoreSpace(tag.substring(index + 1), keyword)
}
if (keywordMatches || containsIgnoreSpace(hint, keyword)) {
emit(Pair(hint, tag))
}
}
}
private fun containsIgnoreSpace(text: String?, key: String): Boolean {
return text != null && text.replace(" ", "").contains(key.replace(" ", ""))
}
private val NAMESPACE_TO_PREFIX = HashMap<String, String>().also {
it["artist"] = "a"
it["cosplayer"] = "cos"
it["character"] = "c"
it["female"] = "f"
it["group"] = "g"
it["language"] = "l"
it["male"] = "m"
it["mixed"] = "x"
it["other"] = "o"
it["parody"] = "p"
it["reclass"] = "r"
}
@JvmStatic
fun namespaceToPrefix(namespace: String): String? {
return NAMESPACE_TO_PREFIX[namespace]
}
private fun getMetadata(context: Context): Array<String>? {
return context.resources.getStringArray(R.array.tag_translation_metadata)
.takeIf { it.size == 4 }
}
fun isTranslatable(): Boolean {
return EhApplication.application.resources.getBoolean(R.bool.tag_translatable)
}
private fun getFileContent(file: File): String? {
try {
file.source().buffer().use { return it.readString(StandardCharsets.UTF_8) }
} catch (e: IOException) {
return null
}
}
private fun getFileSha1(file: File): String? {
try {
FileInputStream(file).use { stream ->
val digest = MessageDigest.getInstance("SHA-1")
var n: Int
val buffer = ByteArray(4 * 1024)
while (stream.read(buffer).also { n = it } != -1) {
digest.update(buffer, 0, n)
}
return HashCodeUtils.bytesToHexString(digest.digest())
}
} catch (e: IOException) {
return null
} catch (e: NoSuchAlgorithmException) {
return null
}
}
private fun checkData(sha1File: File, dataFile: File): Boolean {
val s1 = getFileContent(sha1File) ?: return false
val s2 = getFileSha1(dataFile) ?: return false
return s1 == s2
}
private fun save(client: OkHttpClient, url: String, file: File): Boolean {
val request: Request = Request.Builder().url(url).build()
val call = client.newCall(request)
try {
call.execute().use { response ->
if (!response.isSuccessful) {
return false
}
val body = response.body
body.byteStream()
.use { ins -> FileOutputStream(file).use { os -> IOUtils.copy(ins, os) } }
return true
}
} catch (t: Throwable) {
FileUtils.delete(file)
t.printStackTrace()
ExceptionUtils.throwIfFatal(t)
return false
}
}
@OptIn(DelicateCoroutinesApi::class)
@JvmStatic
fun update() {
GlobalScope.launch(Dispatchers.IO) {
updateInternal()
}
}
@Synchronized
private fun updateInternal() {
val urls = getMetadata(EhApplication.application)
urls?.let {
val sha1Name = urls[0]
val sha1Url = urls[1]
val dataName = urls[2]
val dataUrl = urls[3]
try {
val dir = AppConfig.getFilesDir("tag-translations")
checkNotNull(dir)
// Check current sha1 and current data
val sha1File = File(dir, sha1Name)
val dataFile = File(dir, dataName)
if (!checkData(sha1File, dataFile)) {
FileUtils.delete(sha1File)
FileUtils.delete(dataFile)
}
// Read current EhTagDatabase
if (!isInitialized() && dataFile.exists()) {
try {
dataFile.source().buffer().use { updateData(it) }
} catch (e: IOException) {
FileUtils.delete(sha1File)
FileUtils.delete(dataFile)
}
}
val client = okHttpClient
// Save new sha1
val tempSha1File = File(dir, "$sha1Name.tmp")
check(save(client, sha1Url, tempSha1File))
// Check new sha1 and current data
if (checkData(tempSha1File, dataFile)) {
// The data is the same
FileUtils.delete(tempSha1File)
return
}
// Save new data
val tempDataFile = File(dir, "$dataName.tmp")
check(save(client, dataUrl, tempDataFile))
// Check new sha1 and new data
if (!checkData(tempSha1File, tempDataFile)) {
FileUtils.delete(tempSha1File)
FileUtils.delete(tempDataFile)
return
}
// Replace current sha1 and current data with new sha1 and new data
FileUtils.delete(sha1File)
FileUtils.delete(dataFile)
tempSha1File.renameTo(sha1File)
tempDataFile.renameTo(dataFile)
// Read new EhTagDatabase
try {
dataFile.source().buffer().use { updateData(it) }
} catch (_: IOException) {
}
} catch (e: Throwable) {
e.printStackTrace()
}
}
}
}
@@ -22,7 +22,7 @@ import java.security.cert.X509Certificate
import javax.net.ssl.X509TrustManager
@SuppressLint("CustomX509TrustManager")
class EhX509TrustManager : X509TrustManager {
object EhX509TrustManager : X509TrustManager {
@SuppressLint("TrustAllX509TrustManager")
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
}
@@ -126,7 +126,7 @@ public class EhPageLoader extends PageLoader2 implements SpiderQueen.OnSpiderLis
@Override
protected void onRequest(int index) {
if (mSpiderQueen != null) {
Object object = mSpiderQueen.request(index);
Object object = mSpiderQueen.request(index, true);
if (object instanceof Float) {
notifyPagePercent(index, (Float) object);
} else if (object instanceof String) {
@@ -186,7 +186,9 @@ public class EhPageLoader extends PageLoader2 implements SpiderQueen.OnSpiderLis
@Override
public void onPageSuccess(int index, int finished, int downloaded, int total) {
notifyDataChanged(index);
if (mSpiderQueen != null) {
mSpiderQueen.request(index, false);
}
}
@Override
@@ -418,8 +418,8 @@ public final class SpiderQueen implements Runnable {
return request(index, true, true, false);
}
public Object request(int index) {
return request(index, true, false, true);
public Object request(int index, boolean addNeighbor) {
return request(index, true, false, addNeighbor);
}
private int getPageState(int index) {
@@ -527,7 +527,7 @@ public final class SpiderQueen implements Runnable {
synchronized (mDecodeRequestQueue) {
if (!contain(mDecodeIndexArray, index) && !mDecodeRequestQueue.contains(index)) {
mDecodeRequestQueue.add(index);
mDecodeRequestQueue.notify();
mDecodeRequestQueue.notifyAll();
}
}
result = null;
@@ -30,6 +30,7 @@ import androidx.annotation.RequiresApi
import androidx.annotation.StyleRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
@@ -69,6 +70,8 @@ abstract class EhActivity : AppCompatActivity() {
WindowInsetsHelper.LISTENER
)
super.onCreate(savedInstanceState)
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars =
(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES) <= 0
window.decorView.post {
val rootWindowInsets = window.decorView.rootWindowInsets
if (rootWindowInsets != null && rootWindowInsets.systemWindowInsetBottom >= Resources.getSystem().displayMetrics.density * 40) {
@@ -309,8 +309,6 @@ public final class MainActivity extends StageActivity
} else {
onRestore(savedInstanceState);
}
EhTagDatabase.update(this);
}
@@ -41,8 +41,6 @@ class SettingsActivity : EhActivity() {
mFab = findViewById(R.id.fab)
mAppbarLayout = findViewById(R.id.appbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars =
(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES) <= 0
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
@@ -19,6 +19,7 @@ import android.app.Activity
import android.content.res.Configuration
import android.os.Bundle
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.ListPreference
import androidx.preference.Preference
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.R
@@ -36,6 +37,7 @@ class EhFragment : BasePreferenceFragment() {
val listThumbSize = findPreference<Preference>(Settings.KEY_LIST_THUMB_SIZE)
val detailSize = findPreference<Preference>(Settings.KEY_DETAIL_SIZE)
val thumbSize = findPreference<Preference>(Settings.KEY_THUMB_SIZE)
val thumbResolution = findPreference<Preference>(Settings.KEY_THUMB_RESOLUTION)
val showTagTranslations = findPreference<Preference>(Settings.KEY_SHOW_TAG_TRANSLATIONS)
val tagTranslationsSource = findPreference<Preference>("tag_translations_source")
Settings.getDisplayName()?.let { account?.summary = it }
@@ -47,7 +49,10 @@ class EhFragment : BasePreferenceFragment() {
thumbSize!!.onPreferenceChangeListener = this
showTagTranslations!!.onPreferenceChangeListener = this
blackDarkTheme!!.onPreferenceChangeListener = this
if (!EhTagDatabase.isPossible(requireActivity())) {
thumbResolution!!.setSummaryProvider {
getString(R.string.settings_eh_thumb_resolution_summary, (it as ListPreference).entry)
}
if (!EhTagDatabase.isTranslatable()) {
preferenceScreen.removePreference(showTagTranslations)
preferenceScreen.removePreference(tagTranslationsSource!!)
}
@@ -75,7 +80,7 @@ class EhFragment : BasePreferenceFragment() {
requireActivity().setResult(Activity.RESULT_OK)
} else if (Settings.KEY_SHOW_TAG_TRANSLATIONS == key) {
if (java.lang.Boolean.TRUE == newValue) {
EhTagDatabase.update(requireActivity())
EhTagDatabase.update()
}
} else if (Settings.KEY_BLACK_DARK_THEME == key) {
if (requireActivity().resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES > 0) {
@@ -1,36 +0,0 @@
/*
* Copyright 2016 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hippo.ehviewer.ui.fragment;
import android.os.Bundle;
import androidx.annotation.Nullable;
import com.hippo.ehviewer.R;
public class ReadFragment extends BasePreferenceFragment {
@Override
public void onCreatePreferences(@Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.read_settings);
}
@Override
public int getFragmentTitle() {
return R.string.settings_read;
}
}
@@ -200,11 +200,6 @@ public abstract class BaseScene extends SceneFragment {
// Hide soft ime
hideSoftInput();
insetsController = getInsetsController();
if (insetsController != null) {
insetsController.setAppearanceLightStatusBars((requireActivity().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) <= 0);
}
}
@Nullable
@@ -927,7 +927,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
mNoTags.setVisibility(View.GONE);
}
EhTagDatabase ehTags = Settings.getShowTagTranslations() ? EhTagDatabase.getInstance(context) : null;
EhTagDatabase ehTags = Settings.getShowTagTranslations() ? EhTagDatabase.INSTANCE : null;
int colorTag = ResourcesKt.resolveColor(getTheme(), R.attr.tagBackgroundColor);
int colorName = ResourcesKt.resolveColor(getTheme(), R.attr.tagGroupBackgroundColor);
for (GalleryTagGroup tg : tagGroups) {
@@ -936,8 +936,8 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
mTags.addView(ll);
String readableTagName = null;
if (ehTags != null) {
readableTagName = ehTags.getTranslation("n:" + tg.groupName);
if (ehTags != null && ehTags.isInitialized()) {
readableTagName = ehTags.getTranslation("n", tg.groupName);
}
TextView tgName = (TextView) inflater.inflate(R.layout.item_gallery_tag, ll, false);
@@ -946,9 +946,6 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
tgName.setBackgroundTintList(ColorStateList.valueOf(colorName));
String prefix = EhTagDatabase.namespaceToPrefix(tg.groupName);
if (prefix == null) {
prefix = "";
}
AutoWrapLayout awl = new AutoWrapLayout(context);
ll.addView(awl, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -959,7 +956,7 @@ public class GalleryDetailScene extends CollapsingToolbarScene implements View.O
String readableTag = null;
if (ehTags != null) {
readableTag = ehTags.getTranslation(prefix + tagStr);
readableTag = ehTags.getTranslation(prefix, tagStr);
}
tag.setText(readableTag != null ? readableTag : tagStr);
@@ -11,6 +11,7 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.CallSuper
import androidx.core.widget.addTextChangedListener
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.search.SearchBar
@@ -18,9 +19,15 @@ import com.google.android.material.search.SearchView
import com.google.android.material.shape.MaterialShapeDrawable
import com.hippo.app.BaseDialogBuilder
import com.hippo.ehviewer.R
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhTagDatabase
import com.hippo.ehviewer.widget.SearchDatabase
import com.hippo.scene.StageActivity
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
abstract class SearchBarScene : ToolbarScene() {
@@ -220,10 +227,13 @@ abstract class SearchBarScene : ToolbarScene() {
}
inner class TagSuggestion constructor(private var mHint: String, private var mKeyword: String) :
inner class TagSuggestion constructor(
private var mHint: String?,
private var mKeyword: String
) :
Suggestion() {
override fun getText(textView: TextView): CharSequence {
override fun getText(textView: TextView): CharSequence? {
return if (textView.id == android.R.id.text1) {
mKeyword
} else {
@@ -277,32 +287,43 @@ abstract class SearchBarScene : ToolbarScene() {
@SuppressLint("NotifyDataSetChanged")
private fun updateSuggestions(scrollToTop: Boolean = true) {
val suggestions = arrayListOf<Suggestion>()
val text = mSearchView?.editText?.text?.toString() ?: return
mSuggestionProvider?.run {
providerSuggestions(text)?.let { suggestions.addAll(it) }
}
mSearchDatabase.getSuggestions(text, 128).forEach { suggestions.add(KeywordSuggestion(it)) }
val ehTagDatabase = EhTagDatabase.getInstance(context)
if (!TextUtils.isEmpty(text) && ehTagDatabase != null && !text.endsWith(" ")) {
val s = text.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (s.isNotEmpty()) {
val keyword = s[s.size - 1]
val searchHints = ehTagDatabase.suggest(keyword)
for (searchHint in searchHints) {
suggestions.add(TagSuggestion(searchHint.first, searchHint.second))
}
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Default) {
val suggestions = mutableListOf<Suggestion>()
mergedSuggestionFlow().collect {
suggestions.add(it)
}
withContext(Dispatchers.Main) {
mSuggestionList = suggestions
mSuggestionAdapter?.notifyDataSetChanged()
}
}
mSuggestionList = suggestions
mSuggestionAdapter?.notifyDataSetChanged()
if (scrollToTop) {
mRecyclerView?.scrollToPosition(0)
}
}
private fun mergedSuggestionFlow(): Flow<Suggestion> = flow {
mSearchView?.editText?.text?.toString()?.let { text ->
mSuggestionProvider?.run { providerSuggestions(text)?.forEach { emit(it) } }
mSearchDatabase.getSuggestions(text, 128).forEach { emit(KeywordSuggestion(it)) }
EhTagDatabase.takeIf { it.isInitialized() }?.run {
if (!TextUtils.isEmpty(text) && !text.endsWith(" ")) {
val s = text.split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
if (s.isNotEmpty()) {
val keyword = s[s.size - 1]
val translate = Settings.getShowTagTranslations() && isTranslatable()
suggestFlow(keyword, translate, true).collect {
emit(TagSuggestion(it.first, it.second))
}
suggestFlow(keyword, translate).collect {
emit(TagSuggestion(it.first, it.second))
}
}
}
}
}
}
fun setSuggestionProvider(suggestionProvider: SuggestionProvider) {
mSuggestionProvider = suggestionProvider
}
+6 -8
View File
@@ -17,6 +17,7 @@
*/
package com.hippo.image
import android.graphics.ColorSpace
import android.graphics.ImageDecoder
import android.graphics.ImageDecoder.ALLOCATOR_HARDWARE
import android.graphics.ImageDecoder.DecodeException
@@ -41,6 +42,7 @@ class Image private constructor(source: Source?, val release: () -> Unit = {}) {
mObtainedDrawable =
ImageDecoder.decodeDrawable(source) { decoder: ImageDecoder, info: ImageInfo, src: Source ->
decoder.allocator = ALLOCATOR_HARDWARE
decoder.setTargetColorSpace(colorSpace)
decoder.setTargetSampleSize(
max(
min(
@@ -77,14 +79,10 @@ class Image private constructor(source: Source?, val release: () -> Unit = {}) {
}
companion object {
var screenWidth: Int = 0
var screenHeight: Int = 0
init {
val context = EhApplication.application
screenWidth = context.resources.displayMetrics.widthPixels
screenHeight = context.resources.displayMetrics.heightPixels
}
val screenWidth = EhApplication.application.resources.displayMetrics.widthPixels
val screenHeight = EhApplication.application.resources.displayMetrics.heightPixels
val isWideColorGamut = EhApplication.application.resources.configuration.isScreenWideColorGamut
val colorSpace = ColorSpace.get(if (isWideColorGamut) ColorSpace.Named.DISPLAY_P3 else ColorSpace.Named.SRGB)
@Throws(DecodeException::class)
@JvmStatic
@@ -39,4 +39,23 @@ public class HashCodeUtils {
}
return hash;
}
/**
* http://stackoverflow.com/questions/332079
*
* @param bytes The bytes to convert.
* @return A {@link String} converted from the bytes of a hashable key used
* to store a filename on the disk, to hex digits.
*/
public static String bytesToHexString(final byte[] bytes) {
final StringBuilder builder = new StringBuilder();
for (final byte b : bytes) {
final String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
builder.append('0');
}
builder.append(hex);
}
return builder.toString();
}
}
@@ -161,7 +161,7 @@ class ReaderActivity : EhActivity() {
}
}
}
private var mGalleryProvider: PageLoader2? = null
var mGalleryProvider: PageLoader2? = null
private var mSize: Int = 0
private var mCurrentIndex: Int = 0
private var mSavingPage = -1
@@ -278,13 +278,12 @@ class ReaderActivity : EhActivity() {
}
ArchivePageLoader.showPasswd = ShowPasswdDialogHandler(this)
mGalleryProvider!!.start()
// Get start page
val startPage: Int = if (savedInstanceState == null) {
if (mPage >= 0) mPage else mGalleryProvider!!.startPage
} else {
mCurrentIndex
if (savedInstanceState == null) {
mCurrentIndex = if (mPage >= 0) mPage else mGalleryProvider!!.startPage
}
mCurrentIndex = startPage
lifecycleScope.launch(Dispatchers.Main) {
mGalleryProvider!!.state.collect {
@@ -295,8 +294,6 @@ class ReaderActivity : EhActivity() {
}
}
mGalleryProvider!!.start()
config = ReaderConfig()
initializeMenu()
}
@@ -637,18 +634,6 @@ class ReaderActivity : EhActivity() {
binding.readerMenu.isVisible = true
if (animate) {
val toolbarAnimation = AnimationUtils.loadAnimation(this, R.anim.enter_from_top)
toolbarAnimation.applySystemAnimatorScale(this)
toolbarAnimation.setAnimationListener(
object : SimpleAnimationListener() {
override fun onAnimationStart(animation: Animation) {
// Fix status bar being translucent the first time it's opened.
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
}
},
)
binding.toolbar.startAnimation(toolbarAnimation)
val bottomAnimation = AnimationUtils.loadAnimation(this, R.anim.enter_from_bottom)
bottomAnimation.applySystemAnimatorScale(this)
binding.readerMenuBottom.startAnimation(bottomAnimation)
@@ -664,19 +649,15 @@ class ReaderActivity : EhActivity() {
}
if (animate) {
val toolbarAnimation = AnimationUtils.loadAnimation(this, R.anim.exit_to_top)
toolbarAnimation.applySystemAnimatorScale(this)
toolbarAnimation.setAnimationListener(
val bottomAnimation = AnimationUtils.loadAnimation(this, R.anim.exit_to_bottom)
bottomAnimation.applySystemAnimatorScale(this)
bottomAnimation.setAnimationListener(
object : SimpleAnimationListener() {
override fun onAnimationEnd(animation: Animation) {
binding.readerMenu.isVisible = false
}
},
)
binding.toolbar.startAnimation(toolbarAnimation)
val bottomAnimation = AnimationUtils.loadAnimation(this, R.anim.exit_to_bottom)
bottomAnimation.applySystemAnimatorScale(this)
binding.readerMenuBottom.startAnimation(bottomAnimation)
}
@@ -691,17 +672,6 @@ class ReaderActivity : EhActivity() {
*/
@SuppressLint("PrivateResource")
private fun initializeMenu() {
setSupportActionBar(binding.toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
binding.toolbar.setNavigationOnClickListener {
onBackPressedDispatcher.onBackPressed()
}
binding.toolbar.applyInsetter {
type(navigationBars = true, statusBars = true) {
margin(top = true, horizontal = true)
}
}
binding.readerMenuBottom.applyInsetter {
type(navigationBars = true) {
margin(bottom = true, horizontal = true)
@@ -730,10 +700,9 @@ class ReaderActivity : EhActivity() {
initBottomShortcuts()
val toolbarBackground = (binding.toolbar.background as MaterialShapeDrawable).apply {
elevation =
resources.getDimension(com.google.android.material.R.dimen.m3_sys_elevation_level2)
alpha = 0
val toolbarBackground = MaterialShapeDrawable.createWithElevationOverlay(this).apply {
elevation = resources.getDimension(com.google.android.material.R.dimen.m3_sys_elevation_level2)
alpha = if (isNightMode()) 230 else 242 // 90% dark 95% light
}
binding.toolbarBottom.background = toolbarBackground.copy(this@ReaderActivity)
@@ -816,7 +785,7 @@ class ReaderActivity : EhActivity() {
setTooltip(R.string.action_settings)
val readerSettingSheetDialog = ReaderSettingsSheet(this@ReaderActivity)
setOnClickListener {
if (!readerSettingSheetDialog.isShowing()) {
if (!readerSettingSheetDialog.isShowing) {
readerSettingSheetDialog.show()
}
}
@@ -910,7 +879,8 @@ class ReaderActivity : EhActivity() {
binding.pageSlider.valueTo = max(pages.lastIndex.toFloat(), 1f)
binding.pageSlider.value = page.index.toFloat()
mGalleryProvider?.putStartPage(page.index)
mCurrentIndex = page.index
mGalleryProvider?.putStartPage(mCurrentIndex)
}
/**
@@ -42,10 +42,6 @@ abstract class PageLoader {
state.compareAndSet(STATE_WAIT, STATE_READY)
}
fun notifyDataChanged(index: Int) {
onRequest(index)
}
fun notifyPageWait(index: Int) {
mPages[index].status.value = Page.State.QUEUE
}
@@ -47,5 +47,10 @@ class ReaderGeneralSettings @JvmOverloads constructor(context: Context, attrs: A
binding.keepscreen.bindToPreference(readerPreferences.keepScreenOn())
binding.longTap.bindToPreference(readerPreferences.readWithLongTap())
binding.pageTransitions.bindToPreference(readerPreferences.pageTransitions())
binding.volumePage.bindToPreference(readerPreferences.readWithVolumeKeys())
binding.reserveVolumePage.bindToPreference(readerPreferences.readWithVolumeKeysInverted())
readerPreferences.readWithVolumeKeys().asHotFlow {
binding.reserveVolumePage.isVisible = it
}.launchIn((context as ReaderActivity).lifecycleScope)
}
}
@@ -1,6 +1,7 @@
package eu.kanade.tachiyomi.ui.reader.setting
import android.animation.ValueAnimator
import android.os.Build
import android.os.Bundle
import com.google.android.material.tabs.TabLayout
import com.hippo.ehviewer.R
@@ -32,7 +33,11 @@ class ReaderSettingsSheet(
ValueAnimator.ofFloat(sheetBackgroundDim, 0f).also { valueAnimator ->
valueAnimator.duration = 250
valueAnimator.addUpdateListener {
window?.setDimAmount(it.animatedValue as Float)
window?.run {
setDimAmount(it.animatedValue as Float)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
attributes.blurBehindRadius = (it.animatedValue as Float * 50).toInt()
}
}
}
}
@@ -203,7 +203,7 @@ class PagerPageHolder(
errorLayout = ReaderErrorBinding.inflate(LayoutInflater.from(context), this, true)
errorLayout?.actionRetry?.viewer = viewer
errorLayout?.actionRetry?.setOnClickListener {
TODO()
viewer.activity.mGalleryProvider?.request(page.index)
}
}
errorLayout?.root?.isVisible = true
@@ -61,6 +61,10 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
}
}
override fun destroyView(container: ViewGroup, position: Int, view: View) {
currentChapter?.cancelRequest(position)
}
/**
* Returns the current position of the given [view] on the adapter.
*/
@@ -84,6 +84,7 @@ class WebtoonAdapter(val viewer: WebtoonViewer) : RecyclerView.Adapter<RecyclerV
* Recycles an existing view [holder] before adding it to the view pool.
*/
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
currentChapter?.cancelRequest(holder.bindingAdapterPosition)
when (holder) {
is WebtoonPageHolder -> holder.recycle()
}
@@ -232,7 +232,7 @@ class WebtoonPageHolder(
errorLayout = ReaderErrorBinding.inflate(LayoutInflater.from(context), frame, true)
errorLayout?.root?.layoutParams = FrameLayout.LayoutParams(MATCH_PARENT, (parentHeight * 0.8).toInt())
errorLayout?.actionRetry?.setOnClickListener {
TODO()
viewer.activity.mGalleryProvider?.request(page!!.index)
}
}
return errorLayout!!
@@ -12,16 +12,14 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.WebtoonLayoutManager
import eu.kanade.tachiyomi.ui.reader.loader.PageLoader
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
import eu.kanade.tachiyomi.ui.reader.loader.PageLoader
import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
import eu.kanade.tachiyomi.ui.reader.viewer.BaseViewer
import eu.kanade.tachiyomi.ui.reader.viewer.ViewerNavigation.NavigationRegion
import eu.kanade.tachiyomi.util.system.logcat
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlin.math.max
import kotlin.math.min
/**
* Implementation of a [BaseViewer] to display pages with a [RecyclerView].
@@ -171,9 +169,7 @@ class WebtoonViewer(val activity: ReaderActivity, val isContinuous: Boolean = tr
val position = adapter.items.indexOf(page)
if (position != -1) {
layoutManager.scrollToPositionWithOffset(position, 0)
if (layoutManager.findLastEndVisibleItemPosition() == -1) {
onScrolled(pos = position)
}
onScrolled(pos = position)
} else {
logcat { "Page $page not found in adapter" }
}
@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2016 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?colorPrimary"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="@string/pd_book_open" />
</vector>
@@ -50,12 +50,6 @@
android:visibility="invisible"
tools:visibility="visible">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize" />
<LinearLayout
android:id="@+id/reader_menu_bottom"
android:layout_width="match_parent"
@@ -73,6 +73,24 @@
android:text="@string/pref_page_transitions"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/volume_page"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/settings_read_volume_page"
android:textColor="?android:attr/textColorSecondary" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/reserve_volume_page"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingVertical="16dp"
android:text="@string/settings_read_reverse_volume"
android:textColor="?android:attr/textColorSecondary" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
-31
View File
@@ -284,36 +284,7 @@
<string name="settings_eh_show_jpn_title">Japanische Titel anzeigen</string>
<string name="settings_eh_filter">Galerie-Blocker</string>
<string name="settings_eh_filter_summary">Nach Titel, Uploader order Etiketten die unerwünschten Galerien verstecken</string>
<string name="settings_read">Lesen</string>
<string name="settings_read_screen_rotation">Richtung des Bildschirms</string>
<string name="settings_read_screen_rotation_default">Standard</string>
<string name="settings_read_screen_rotation_portrait">Querformat</string>
<string name="settings_read_screen_rotation_landscape">Hochformat</string>
<string name="settings_read_reading_direction">Richtung des Lesens</string>
<string name="settings_read_reading_direction_left_to_right">Von links nach rechts</string>
<string name="settings_read_reading_direction_right_to_Left">Von rechts nach links</string>
<string name="settings_read_reading_direction_top_to_bottom">Von oben nach unter</string>
<string name="settings_read_page_scaling">Seitenskalierung</string>
<string name="settings_read_page_scaling_actual_size">Originale Größe</string>
<string name="settings_read_page_scaling_fit_to_width">Nach der Länge anpassen</string>
<string name="settings_read_page_scaling_fit_to_height">Nach der Höhe anpassen</string>
<string name="settings_read_page_scaling_fit_to_screen">Nach dem Bildschirm anpassen</string>
<string name="settings_read_page_scaling_fixed_scale">Festgesetzte Größe</string>
<string name="settings_read_start_position">Seiten umblättern von</string>
<string name="settings_read_start_position_top_left">Oben links</string>
<string name="settings_read_start_position_top_right">Oben rechts</string>
<string name="settings_read_start_position_bottom_left">Unter links</string>
<string name="settings_read_start_position_bottom_right">Unter rechts</string>
<string name="settings_read_start_position_center">Die Mitte</string>
<string name="settings_read_keep_screen_on">Bildschirm wach bleiben lassen</string>
<string name="settings_read_show_clock">Uhr anzeigen</string>
<string name="settings_read_show_progress">Fortschritt anzeigen</string>
<string name="settings_read_show_battery">Akku-Niveau anzeigen</string>
<string name="settings_read_show_page_interval">Seitensabstand anzeigen</string>
<string name="settings_read_volume_page">Seiten mit Lautstärketaste umblättern</string>
<string name="settings_read_reading_fullscreen">Vollbild</string>
<string name="settings_read_custom_screen_lightness">Helligkeit manuell festlegen</string>
<string name="settings_read_screen_lightness">Helligkeit</string>
<string name="settings_download">Download</string>
<string name="settings_download_download_location">Downloadziel</string>
<string name="settings_download_invalid_download_location">Ungültiges Downloadziel</string>
@@ -416,8 +387,6 @@
<string name="settings_advanced_custom_hosts_summary">Hostname auf die angepassten IP umstellen\nDie Regeln können die von der App festgelegt überschreiben</string>
<string name="download_reset_reading_progress">Lesefortschritte zurücksetzen</string>
<string name="reset_reading_progress_message">Lesefortschritte aus allen heruntergeladenen Galerie zurücksetzen?</string>
<string name="settings_eh_theme_light">Weiß</string>
<string name="settings_eh_theme_dark">Dunkel</string>
<string name="settings_eh_identity_cookies_signed">Wenn jemand die folgenden Informationen hat, kann er sich als du anmelden. &lt;br&gt;&lt;b&gt;ALSO GEHEIM HALTEN!&lt;/b&gt;&lt;br&gt;&lt;br&gt;%s</string>
<string name="settings_eh_identity_cookies_tourist">Du hast dich noch nicht angemeldet.</string>
<string name="settings_eh_identity_cookies_copy">Kopieren</string>
-31
View File
@@ -304,36 +304,7 @@
<string name="settings_eh_filter">Filtrado de galerías</string>
<string name="settings_eh_filter_summary">Filtrado de galerías por título, uploader y etiquetas. Para más detalles presiona el ícono (i) en la parte superior del menú</string>
<string name="settings_read">Lectura</string>
<string name="settings_read_screen_rotation">Orientación de la pantalla</string>
<string name="settings_read_screen_rotation_default">Defecto</string>
<string name="settings_read_screen_rotation_portrait">Retrato</string>
<string name="settings_read_screen_rotation_landscape">Paisaje</string>
<string name="settings_read_reading_direction">Dirección de lectura</string>
<string name="settings_read_reading_direction_left_to_right">Izquierda a derecha</string>
<string name="settings_read_reading_direction_right_to_Left">Derecha a izquierda</string>
<string name="settings_read_reading_direction_top_to_bottom">Arriba hacia abajo</string>
<string name="settings_read_page_scaling">Escala de página</string>
<string name="settings_read_page_scaling_actual_size">Tamaño original</string>
<string name="settings_read_page_scaling_fit_to_width">Ajustar a anchura</string>
<string name="settings_read_page_scaling_fit_to_height">Ajustar a altura</string>
<string name="settings_read_page_scaling_fit_to_screen">Ajustar a pantalla</string>
<string name="settings_read_page_scaling_fixed_scale">Escala fija</string>
<string name="settings_read_start_position">Posición de inicio</string>
<string name="settings_read_start_position_top_left">Arriba a la izquierda</string>
<string name="settings_read_start_position_top_right">Abajo a la derecha</string>
<string name="settings_read_start_position_bottom_left">Abajo a la izquierda</string>
<string name="settings_read_start_position_bottom_right">Abajo a la derecha</string>
<string name="settings_read_start_position_center">Centro</string>
<string name="settings_read_keep_screen_on">Pantalla siempre encendida</string>
<string name="settings_read_show_page_interval">Mostrar intervalo de página</string>
<string name="settings_read_show_clock">Mostrar hora</string>
<string name="settings_read_show_progress">Mostrar progreso de lectura</string>
<string name="settings_read_show_battery">Mostrar porcentaje de la batería</string>
<string name="settings_read_volume_page">Pasar páginas con botón del volumen</string>
<string name="settings_read_reading_fullscreen">Pantalla completa</string>
<string name="settings_read_custom_screen_lightness">Personalizar brillo de la pantalla</string>
<string name="settings_read_screen_lightness">Brillo de la pantalla</string>
<string name="settings_download">Descargas</string>
<string name="settings_download_download_location">Ruta de descargas</string>
@@ -501,7 +472,5 @@
<string name="edit_host_delete">Borrar</string>
<string name="invalid_host">Anfitrión inválida</string>
<string name="invalid_ip">IP inválida</string>
<string name="settings_eh_theme_light">Claro</string>
<string name="settings_eh_theme_dark">Oscuro</string>
</resources>
-31
View File
@@ -339,36 +339,7 @@
<string name="settings_eh_filter">Bloqueur des galeries</string>
<string name="settings_eh_filter_summary">Filtrer les galerie par les titres, les uploaders ou les tags</string>
<string name="settings_read">Lecture</string>
<string name="settings_read_screen_rotation">Rotation d\'écran</string>
<string name="settings_read_screen_rotation_default">Par défaut</string>
<string name="settings_read_screen_rotation_portrait">Portrait</string>
<string name="settings_read_screen_rotation_landscape">Landscape</string>
<string name="settings_read_reading_direction">Direction de lecture</string>
<string name="settings_read_reading_direction_left_to_right">De gauche à droit</string>
<string name="settings_read_reading_direction_right_to_Left">De droit à gauche</string>
<string name="settings_read_reading_direction_top_to_bottom">De haut à fond</string>
<string name="settings_read_page_scaling">Écaillage de page</string>
<string name="settings_read_page_scaling_actual_size">Taille actuelle</string>
<string name="settings_read_page_scaling_fit_to_width">S\'adapter à la largueur</string>
<string name="settings_read_page_scaling_fit_to_height">S\'adapter à la hauteur</string>
<string name="settings_read_page_scaling_fit_to_screen">S\'adapter à l\'écran</string>
<string name="settings_read_page_scaling_fixed_scale">Taille fixée</string>
<string name="settings_read_start_position">Position de début</string>
<string name="settings_read_start_position_top_left">En haut à gauche</string>
<string name="settings_read_start_position_top_right">En haut à droit</string>
<string name="settings_read_start_position_bottom_left">En bas à gauche</string>
<string name="settings_read_start_position_bottom_right">En bas à droit</string>
<string name="settings_read_start_position_center">Centre</string>
<string name="settings_read_keep_screen_on">Maintenir l\'écran allumé</string>
<string name="settings_read_show_clock">Montrer l\'heure</string>
<string name="settings_read_show_progress">Montrer le progrès</string>
<string name="settings_read_show_battery">Montrer le niveau de batterie</string>
<string name="settings_read_show_page_interval">Montrer l\'intervalle des pages</string>
<string name="settings_read_volume_page">Tourner la page avec les Volumes</string>
<string name="settings_read_reading_fullscreen">Plein d\'écran</string>
<string name="settings_read_custom_screen_lightness">Personaliser la luminosité d\'écran</string>
<string name="settings_read_screen_lightness">Luminosité d\'écran</string>
<!-- My Tags Activity -->
<string name="my_tags">Tags suivis</string>
@@ -526,8 +497,6 @@
<string name="settings_advanced_custom_hosts_title">hosts.txt personalisé</string>
<string name="settings_advanced_custom_hosts_summary">Mapper l\'hôte à l\'adresse IP\nIls pouvent redéfinir l\'hosts.txt de l\'app</string>
<string name="app_language_system">Langue du système (défaut)</string>
<string name="settings_eh_theme_light">Blanc</string>
<string name="settings_eh_theme_dark">Gris</string>
<string name="settings_eh_identity_cookies_signed">Tout le monde peut utiliser les cookies de ce compte pour s\'y connecter.&lt;br&gt;&lt;b&gt;GARDEZ-LES BIEN !&lt;/b&gt;&lt;br&gt;&lt;br&gt;%s</string>
<string name="settings_eh_identity_cookies_tourist">Vous ne vous êtes pas connecté.</string>
<string name="settings_eh_identity_cookies_copy">Copier</string>
-31
View File
@@ -337,36 +337,7 @@
<string name="settings_eh_filter">ギャラリーをブロック</string>
<string name="settings_eh_filter_summary">タイトル、アップローダ、もしくはタグで望ましくないギャラリーを除外</string>
<string name="settings_read">閲覧</string>
<string name="settings_read_screen_rotation">画面の向き</string>
<string name="settings_read_screen_rotation_default">システムデフォルト</string>
<string name="settings_read_screen_rotation_portrait">縦画面</string>
<string name="settings_read_screen_rotation_landscape">横画面</string>
<string name="settings_read_reading_direction">閲覧方向</string>
<string name="settings_read_reading_direction_left_to_right">左から右へ</string>
<string name="settings_read_reading_direction_right_to_Left">右から左へ</string>
<string name="settings_read_reading_direction_top_to_bottom">上から下へ</string>
<string name="settings_read_page_scaling">ページのズーム</string>
<string name="settings_read_page_scaling_actual_size">元のサイズ</string>
<string name="settings_read_page_scaling_fit_to_width">幅に合わせる</string>
<string name="settings_read_page_scaling_fit_to_height">長さに合わせる</string>
<string name="settings_read_page_scaling_fit_to_screen">画面に合わせる</string>
<string name="settings_read_page_scaling_fixed_scale">固定したスケール</string>
<string name="settings_read_start_position">ページを開く位置</string>
<string name="settings_read_start_position_top_left">左上隅</string>
<string name="settings_read_start_position_top_right">右上隅</string>
<string name="settings_read_start_position_bottom_left">左下隅</string>
<string name="settings_read_start_position_bottom_right">右下隅</string>
<string name="settings_read_start_position_center">中心</string>
<string name="settings_read_keep_screen_on">画面を常にオン</string>
<string name="settings_read_show_clock">時計を表示</string>
<string name="settings_read_show_progress">進捗を表示</string>
<string name="settings_read_show_battery">バッテリー残量を表示</string>
<string name="settings_read_show_page_interval">ページ間の余白を表示</string>
<string name="settings_read_volume_page">ボリュームキーでページをめくる</string>
<string name="settings_read_reading_fullscreen">フルスクリーン</string>
<string name="settings_read_custom_screen_lightness">画面の明るさを設定</string>
<string name="settings_read_screen_lightness">画面の明るさ</string>
<!-- My Tags Activity -->
@@ -524,8 +495,6 @@
<string name="settings_advanced_custom_hosts_title">カスタムhosts.txt</string>
<string name="settings_advanced_custom_hosts_summary">ホスト名をIPにマッピング\n既定のhosts.txtを上書きできます。</string>
<string name="settings_eh_theme_light">ライト</string>
<string name="settings_eh_theme_dark">ダーク</string>
<string name="settings_eh_identity_cookies_signed">下記の情報を持つ誰でもこのアカウントにログインできますので&lt;br&gt;&lt;b&gt;絶対に他人に渡さないように!&lt;/b&gt;&lt;br&gt;&lt;br&gt;%s</string>
<string name="settings_eh_identity_cookies_tourist">まだログインしていません</string>
<string name="settings_eh_identity_cookies_copy">コピー</string>
-31
View File
@@ -303,8 +303,6 @@
<string name="settings_u_config">E-Hentai 설정</string>
<string name="settings_u_config_summary">E-Hentai 사이트의 설정 페이지를 엽니다.</string>
<string name="settings_eh_sign_out_tip">로그아웃했습니다. 다시 로그인하려면 앱을 재시작하세요.</string>
<string name="settings_eh_theme_light">밝은 테마</string>
<string name="settings_eh_theme_dark">어두운 테마</string>
<string name="settings_eh_gallery_site">갤러리 사이트</string>
<string name="settings_eh_list_mode">목록 모드</string>
<string name="settings_eh_list_mode_detail">자세히</string>
@@ -324,36 +322,7 @@
<string name="settings_eh_tag_translations_source">Placeholder</string>
<string name="settings_eh_tag_translations_source_url">https://placeholder</string>
<string name="settings_read">읽기</string>
<string name="settings_read_screen_rotation">화면 회전</string>
<string name="settings_read_screen_rotation_default">기본값</string>
<string name="settings_read_screen_rotation_portrait">세로 모드</string>
<string name="settings_read_screen_rotation_landscape">가로 모드</string>
<string name="settings_read_reading_direction">읽기 방향</string>
<string name="settings_read_reading_direction_left_to_right">왼쪽에서 오른쪽으로</string>
<string name="settings_read_reading_direction_right_to_Left">오른쪽에서 왼쪽으로</string>
<string name="settings_read_reading_direction_top_to_bottom">위에서 아래로</string>
<string name="settings_read_page_scaling">페이지 표시</string>
<string name="settings_read_page_scaling_actual_size">실제 크기</string>
<string name="settings_read_page_scaling_fit_to_width">너비에 맞춤</string>
<string name="settings_read_page_scaling_fit_to_height">높이에 맞춤</string>
<string name="settings_read_page_scaling_fit_to_screen">화면에 맞춤</string>
<string name="settings_read_page_scaling_fixed_scale">비율 고정</string>
<string name="settings_read_start_position">시작 위치</string>
<string name="settings_read_start_position_top_left">왼쪽 상단</string>
<string name="settings_read_start_position_top_right">오른쪽 상단</string>
<string name="settings_read_start_position_bottom_left">왼쪽 하단</string>
<string name="settings_read_start_position_bottom_right">오른쪽 하단</string>
<string name="settings_read_start_position_center">중앙</string>
<string name="settings_read_keep_screen_on">화면 켜짐 유지</string>
<string name="settings_read_show_clock">시계 표시</string>
<string name="settings_read_show_progress">독서 진행도 표시</string>
<string name="settings_read_show_battery">배터리 표시</string>
<string name="settings_read_show_page_interval">페이지 간격 표시</string>
<string name="settings_read_volume_page">볼륨 키로 페이지 넘기기</string>
<string name="settings_read_reading_fullscreen">전체 화면</string>
<string name="settings_read_custom_screen_lightness">화면 밝기 사용자 지정</string>
<string name="settings_read_screen_lightness">화면 밝기</string>
<string name="settings_download">다운로드</string>
<string name="settings_download_download_location">다운로드 위치</string>
-31
View File
@@ -318,8 +318,6 @@
<string name="settings_eh_identity_cookies_copy">คัดลอก</string>
<string name="settings_u_config">การตั้งค่า EHentai</string>
<string name="settings_u_config_summary">การตั้งค่าบนเว็บไซต์ EHentai</string>
<string name="settings_eh_theme_light">สว่าง</string>
<string name="settings_eh_theme_dark">มืด</string>
<string name="settings_eh_gallery_site">เว็บไซต์หลักของแกลเลอรี่</string>
<string name="settings_eh_list_mode">มุมองแบบรายการ</string>
<string name="settings_eh_list_mode_detail">แสดงรายละเอียด</string>
@@ -339,36 +337,7 @@
<string name="settings_eh_tag_translations_source">Placeholder</string>
<string name="settings_eh_tag_translations_source_url">https://placeholder</string>
<string name="settings_read">การอ่าน</string>
<string name="settings_read_screen_rotation">ทิศทางของหน้าจอ</string>
<string name="settings_read_screen_rotation_default">ค่าเริ่มต้น</string>
<string name="settings_read_screen_rotation_portrait">แนวตั้ง</string>
<string name="settings_read_screen_rotation_landscape">แนวนอน</string>
<string name="settings_read_reading_direction">ทิศทางการเปิดหน้าอ่าน</string>
<string name="settings_read_reading_direction_left_to_right">ซ้าย -> ขวา</string>
<string name="settings_read_reading_direction_right_to_Left">ขวา -> ซ้าย</string>
<string name="settings_read_reading_direction_top_to_bottom">บน -> ล่าง</string>
<string name="settings_read_page_scaling">ขนาดของหน้า</string>
<string name="settings_read_page_scaling_actual_size">เท่าขนาด</string>
<string name="settings_read_page_scaling_fit_to_width">พอดีกับขนาดแนวกว้าง</string>
<string name="settings_read_page_scaling_fit_to_height">พอดีกับขนาดแนวสูง</string>
<string name="settings_read_page_scaling_fit_to_screen">พอดีกับขนาดหน้าจอ</string>
<string name="settings_read_page_scaling_fixed_scale">ขนาดตายตัว</string>
<string name="settings_read_start_position">ตำแหน่งเริ่มต้น</string>
<string name="settings_read_start_position_top_left">บนซ้าย</string>
<string name="settings_read_start_position_top_right">บนขวา</string>
<string name="settings_read_start_position_bottom_left">ล่างซ้าย</string>
<string name="settings_read_start_position_bottom_right">ล่างขวา</string>
<string name="settings_read_start_position_center">ตรงกลาง</string>
<string name="settings_read_keep_screen_on">เปิดหน้าจอค้างไว้</string>
<string name="settings_read_show_clock">แสดงเวลา</string>
<string name="settings_read_show_progress">แสดงความคืบหน้า</string>
<string name="settings_read_show_battery">แสดงแบตเตอรี่</string>
<string name="settings_read_show_page_interval">แสดงความห่างของหน้าเมื่อเปลี่ยน</string>
<string name="settings_read_volume_page">ใช้ปุ่มปรับเสียงเพื่อเปลี่ยนหน้า</string>
<string name="settings_read_reading_fullscreen">อ่านเต็มจอ</string>
<string name="settings_read_custom_screen_lightness">ปรับความสว่างของหน้าจอ</string>
<string name="settings_read_screen_lightness">แสงหน้าจอ</string>
<string name="settings_download">การดาวน์โหลด</string>
<string name="settings_download_download_location">ตำแหน่งแหล่งดาวน์โหลด</string>
-26
View File
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2019 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string-array name="tag_translation_metadata" tools:ignore="InconsistentArrays">
<item>tag-translations-zh-rCN.sha1</item>
<item>https://raw.githubusercontent.com/Mapaler/EhViewer/tag-translations/tag-translations/tag-translations-zh-rCN.sha1</item>
<item>tag-translations-zh-rCN</item>
<item>https://raw.githubusercontent.com/Mapaler/EhViewer/tag-translations/tag-translations/tag-translations-zh-rCN</item>
</string-array>
</resources>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2022 Tarsin Norbin
~
~ This file is part of EhViewer
~
~ EhViewer is free software: you can redistribute it and/or modify it
~ under the terms of the GNU GeneralPublic License as published
~ by the Free Software Foundation,either version 3 of the License, or
~ (at your option) any later version.
~
~ EhViewer is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License along with EhViewer.
~ If not, see <https://www.gnu.org/licenses/>.
-->
<resources>
<bool name="tag_translatable">true</bool>
</resources>
@@ -356,8 +356,6 @@
<string name="settings_u_config_summary">EHentai 网站上的设置</string>
<string name="settings_my_tags">我的标签</string>
<string name="settings_my_tags_summary">EHentai 网站上的我的标签</string>
<string name="settings_eh_theme_light">亮色</string>
<string name="settings_eh_theme_dark">暗色</string>
<string name="settings_eh_gallery_site">画廊站点</string>
<string name="settings_eh_launch_page">启动页</string>
<string name="settings_eh_list_mode">列表模式</string>
@@ -385,37 +383,7 @@
<string name="settings_eh_filter">屏蔽画廊</string>
<string name="settings_eh_filter_summary">根据标题、上传者、标签屏蔽画廊</string>
<string name="settings_read">阅读</string>
<string name="settings_read_screen_rotation">屏幕方向</string>
<string name="settings_read_screen_rotation_default">系统默认</string>
<string name="settings_read_screen_rotation_portrait">竖屏</string>
<string name="settings_read_screen_rotation_landscape">横屏</string>
<string name="settings_read_screen_rotation_sensor">自动旋转</string>
<string name="settings_read_reading_direction">阅读方向</string>
<string name="settings_read_reading_direction_left_to_right">从左至右</string>
<string name="settings_read_reading_direction_right_to_Left">从右至左</string>
<string name="settings_read_reading_direction_top_to_bottom">从上至下</string>
<string name="settings_read_page_scaling">页面缩放</string>
<string name="settings_read_page_scaling_actual_size">原始尺寸</string>
<string name="settings_read_page_scaling_fit_to_width">匹配宽度</string>
<string name="settings_read_page_scaling_fit_to_height">匹配长度</string>
<string name="settings_read_page_scaling_fit_to_screen">匹配屏幕</string>
<string name="settings_read_page_scaling_fixed_scale">固定缩放</string>
<string name="settings_read_start_position">开页位置</string>
<string name="settings_read_start_position_top_left">左上角</string>
<string name="settings_read_start_position_top_right">右上角</string>
<string name="settings_read_start_position_bottom_left">左下角</string>
<string name="settings_read_start_position_bottom_right">右下角</string>
<string name="settings_read_start_position_center">中心</string>
<string name="settings_read_keep_screen_on">屏幕常亮</string>
<string name="settings_read_show_clock">显示时钟</string>
<string name="settings_read_show_progress">显示进度</string>
<string name="settings_read_show_battery">显示电量</string>
<string name="settings_read_show_page_interval">显示页面间隔</string>
<string name="settings_read_volume_page">使用音量键翻页</string>
<string name="settings_read_reading_fullscreen">全屏</string>
<string name="settings_read_custom_screen_lightness">自定义屏幕亮度</string>
<string name="settings_read_screen_lightness">屏幕亮度</string>
<string name="settings_read_reverse_volume">翻转音量键</string>
<string name="settings_download">下载</string>
@@ -586,8 +554,6 @@
<string name="delete_search_history">从搜索记录中删除“%s”?</string>
<string name="settings_advanced_domain_fronting_title">域名前置</string>
<string name="settings_advanced_domain_fronting_summary">绕过 SNI 封锁</string>
<string name="read_theme">色彩主题</string>
<string name="follow_app">跟随应用</string>
<string name="action_add_tag">添加标签</string>
<string name="action_add_tag_tip">添加新标签,用逗号「,」分割</string>
<string name="comment_user_uploader">%s (上传者)</string>
@@ -620,7 +586,6 @@
<string name="account_name">账户</string>
<!-- Tachiyomi Reader Start-->
<string name="manga">书架中的作品</string>
<string name="action_settings">设置</string>
<string name="action_retry">重试</string>
<string name="action_share">分享</string>
-26
View File
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2019 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string-array name="tag_translation_metadata" tools:ignore="InconsistentArrays">
<item>tag-translations-zh-rCN.sha1</item>
<item>https://raw.githubusercontent.com/Mapaler/EhViewer/tag-translations/tag-translations/tag-translations-zh-rCN.sha1</item>
<item>tag-translations-zh-rCN</item>
<item>https://raw.githubusercontent.com/Mapaler/EhViewer/tag-translations/tag-translations/tag-translations-zh-rCN</item>
</string-array>
</resources>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2022 Tarsin Norbin
~
~ This file is part of EhViewer
~
~ EhViewer is free software: you can redistribute it and/or modify it
~ under the terms of the GNU GeneralPublic License as published
~ by the Free Software Foundation,either version 3 of the License, or
~ (at your option) any later version.
~
~ EhViewer is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License along with EhViewer.
~ If not, see <https://www.gnu.org/licenses/>.
-->
<resources>
<bool name="tag_translatable">true</bool>
</resources>
@@ -354,8 +354,6 @@
<string name="settings_u_config_summary">EHentai 網站上的設置</string>
<string name="settings_my_tags">我的標籤</string>
<string name="settings_my_tags_summary">EHentai 網站上的我的標籤</string>
<string name="settings_eh_theme_light">亮色</string>
<string name="settings_eh_theme_dark">暗色</string>
<string name="settings_eh_gallery_site">畫廊站點</string>
<string name="settings_eh_launch_page">啟動頁</string>
<string name="settings_eh_list_mode">列表模式</string>
@@ -379,36 +377,7 @@
<string name="settings_eh_filter">屏蔽畫廊</string>
<string name="settings_eh_filter_summary">根據標題、上傳者、標籤屏蔽畫廊</string>
<string name="settings_read">閲讀</string>
<string name="settings_read_screen_rotation">屏幕方向</string>
<string name="settings_read_screen_rotation_default">系統默認</string>
<string name="settings_read_screen_rotation_portrait">豎屏</string>
<string name="settings_read_screen_rotation_landscape">橫屏</string>
<string name="settings_read_reading_direction">閲讀方向</string>
<string name="settings_read_reading_direction_left_to_right">從左至右</string>
<string name="settings_read_reading_direction_right_to_Left">從右至左</string>
<string name="settings_read_reading_direction_top_to_bottom">從上至下</string>
<string name="settings_read_page_scaling">頁面縮放</string>
<string name="settings_read_page_scaling_actual_size">原始尺寸</string>
<string name="settings_read_page_scaling_fit_to_width">匹配寬度</string>
<string name="settings_read_page_scaling_fit_to_height">匹配長度</string>
<string name="settings_read_page_scaling_fit_to_screen">匹配屏幕</string>
<string name="settings_read_page_scaling_fixed_scale">固定縮放</string>
<string name="settings_read_start_position">開頁位置</string>
<string name="settings_read_start_position_top_left">左上角</string>
<string name="settings_read_start_position_top_right">右上角</string>
<string name="settings_read_start_position_bottom_left">左下角</string>
<string name="settings_read_start_position_bottom_right">右下角</string>
<string name="settings_read_start_position_center">中心</string>
<string name="settings_read_keep_screen_on">屏幕常亮</string>
<string name="settings_read_show_clock">顯示時鐘</string>
<string name="settings_read_show_progress">顯示進度</string>
<string name="settings_read_show_battery">顯示電量</string>
<string name="settings_read_show_page_interval">顯示頁面間隔</string>
<string name="settings_read_volume_page">使用音量鍵翻頁</string>
<string name="settings_read_reading_fullscreen">全屏</string>
<string name="settings_read_custom_screen_lightness">自定義屏幕亮度</string>
<string name="settings_read_screen_lightness">屏幕亮度</string>
<string name="settings_download">下載</string>
<string name="settings_download_download_location">下載路徑</string>
@@ -549,7 +518,6 @@
<string name="favorite_name">收藏畫廊</string>
<!-- Tachiyomi Reader Start-->
<string name="manga">藏書</string>
<string name="action_settings">設定</string>
<string name="action_retry">重試</string>
<string name="action_share">分享</string>
-26
View File
@@ -1,26 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2019 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources xmlns:tools="http://schemas.android.com/tools">
<string-array name="tag_translation_metadata" tools:ignore="InconsistentArrays">
<item>tag-translations-zh-rCN.sha1</item>
<item>https://raw.githubusercontent.com/Mapaler/EhViewer/tag-translations/tag-translations/tag-translations-zh-rCN.sha1</item>
<item>tag-translations-zh-rCN</item>
<item>https://raw.githubusercontent.com/Mapaler/EhViewer/tag-translations/tag-translations/tag-translations-zh-rCN</item>
</string-array>
</resources>
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2022 Tarsin Norbin
~
~ This file is part of EhViewer
~
~ EhViewer is free software: you can redistribute it and/or modify it
~ under the terms of the GNU GeneralPublic License as published
~ by the Free Software Foundation,either version 3 of the License, or
~ (at your option) any later version.
~
~ EhViewer is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License along with EhViewer.
~ If not, see <https://www.gnu.org/licenses/>.
-->
<resources>
<bool name="tag_translatable">true</bool>
</resources>
@@ -356,8 +356,6 @@
<string name="settings_u_config_summary">EHentai 網站上的設定</string>
<string name="settings_my_tags">我的標籤</string>
<string name="settings_my_tags_summary">EHentai 網站上的我的標籤</string>
<string name="settings_eh_theme_light">淺色</string>
<string name="settings_eh_theme_dark">深色</string>
<string name="settings_eh_gallery_site">圖庫站台</string>
<string name="settings_eh_launch_page">啟動頁</string>
<string name="settings_eh_list_mode">列表模式</string>
@@ -381,37 +379,7 @@
<string name="settings_eh_filter">遮蔽圖庫</string>
<string name="settings_eh_filter_summary">根據標題、上傳者、標籤遮蔽圖庫</string>
<string name="settings_read">閱讀</string>
<string name="settings_read_screen_rotation">螢幕方向</string>
<string name="settings_read_screen_rotation_default">系統預設</string>
<string name="settings_read_screen_rotation_portrait">直向</string>
<string name="settings_read_screen_rotation_landscape">橫向</string>
<string name="settings_read_screen_rotation_sensor">自動旋轉</string>
<string name="settings_read_reading_direction">閱讀方向</string>
<string name="settings_read_reading_direction_left_to_right">由左到右</string>
<string name="settings_read_reading_direction_right_to_Left">由右到左</string>
<string name="settings_read_reading_direction_top_to_bottom">由上到下</string>
<string name="settings_read_page_scaling">頁面縮放</string>
<string name="settings_read_page_scaling_actual_size">原始尺寸</string>
<string name="settings_read_page_scaling_fit_to_width">貼齊寬度</string>
<string name="settings_read_page_scaling_fit_to_height">貼齊長度</string>
<string name="settings_read_page_scaling_fit_to_screen">以螢幕大小縮放</string>
<string name="settings_read_page_scaling_fixed_scale">固定尺寸</string>
<string name="settings_read_start_position">開始位置</string>
<string name="settings_read_start_position_top_left">左上角</string>
<string name="settings_read_start_position_top_right">右上角</string>
<string name="settings_read_start_position_bottom_left">左下角</string>
<string name="settings_read_start_position_bottom_right">右下角</string>
<string name="settings_read_start_position_center">中間</string>
<string name="settings_read_keep_screen_on">保持螢幕開啟</string>
<string name="settings_read_show_clock">顯示時鐘</string>
<string name="settings_read_show_progress">顯示進度</string>
<string name="settings_read_show_battery">顯示電量</string>
<string name="settings_read_show_page_interval">顯示頁面間隔</string>
<string name="settings_read_volume_page">使用音量鍵翻頁</string>
<string name="settings_read_reading_fullscreen">全螢幕</string>
<string name="settings_read_custom_screen_lightness">自訂螢幕亮度</string>
<string name="settings_read_screen_lightness">螢幕亮度</string>
<string name="settings_read_reverse_volume">翻轉音量鍵</string>
<string name="settings_download">下載</string>
@@ -581,8 +549,6 @@
<string name="delete_search_history">從搜索記錄中刪除“%s”?</string>
<string name="settings_advanced_domain_fronting_title">域名前綴</string>
<string name="settings_advanced_domain_fronting_summary">繞過 SNI 封鎖</string>
<string name="read_theme">色彩主題</string>
<string name="follow_app">跟隨應用</string>
<string name="action_add_tag">增加標籤</string>
<string name="action_add_tag_tip">增加新標籤,用逗號「,」分割</string>
<string name="comment_user_uploader">%s (上傳者)</string>
@@ -614,7 +580,6 @@
<string name="account_name">帳號</string>
<!-- Tachiyomi Reader Start-->
<string name="manga">藏書</string>
<string name="action_settings">設定</string>
<string name="action_retry">重試</string>
<string name="action_share">分享</string>
+4 -71
View File
@@ -155,64 +155,6 @@
<item>2400</item>
</string-array>
<string-array name="screen_rotation_entries">
<item>@string/settings_read_screen_rotation_default</item>
<item>@string/settings_read_screen_rotation_portrait</item>
<item>@string/settings_read_screen_rotation_landscape</item>
<item>@string/settings_read_screen_rotation_sensor</item>
</string-array>
<string-array name="screen_rotation_entry_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="reading_direction_entries">
<item>@string/settings_read_reading_direction_left_to_right</item>
<item>@string/settings_read_reading_direction_right_to_Left</item>
<item>@string/settings_read_reading_direction_top_to_bottom</item>
</string-array>
<string-array name="reading_direction_entry_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<string-array name="page_scaling_entries">
<item>@string/settings_read_page_scaling_actual_size</item>
<item>@string/settings_read_page_scaling_fit_to_width</item>
<item>@string/settings_read_page_scaling_fit_to_height</item>
<item>@string/settings_read_page_scaling_fit_to_screen</item>
<item>@string/settings_read_page_scaling_fixed_scale</item>
</string-array>
<string-array name="page_scaling_entry_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</string-array>
<string-array name="start_position_entries">
<item>@string/settings_read_start_position_top_left</item>
<item>@string/settings_read_start_position_top_right</item>
<item>@string/settings_read_start_position_bottom_left</item>
<item>@string/settings_read_start_position_bottom_right</item>
<item>@string/settings_read_start_position_center</item>
</string-array>
<string-array name="start_position_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
</string-array>
<string-array name="read_cache_size_entries" translatable="false">
<item>40 MB</item>
<item>80 MB</item>
@@ -267,7 +209,10 @@
</string-array>
<string-array name="tag_translation_metadata" tools:ignore="InconsistentArrays">
<item>@null</item>
<item>tag-translations-zh-rCN.json.sha1</item>
<item>https://raw.githubusercontent.com/Ehviewer-Overhauled/EhTagTranslation/tag-translations/tag-translations/tag-translations-zh-rCN.json.sha1</item>
<item>tag-translations-zh-rCN.json</item>
<item>https://raw.githubusercontent.com/Ehviewer-Overhauled/EhTagTranslation/tag-translations/tag-translations/tag-translations-zh-rCN.json</item>
</string-array>
<string-array name="proxy_types">
@@ -298,18 +243,6 @@
<item>@string/download_state_failed</item>
</string-array>
<string-array name="read_theme_entries">
<item>@string/follow_app</item>
<item>@string/settings_eh_theme_dark</item>
<item>@string/settings_eh_theme_light</item>
</string-array>
<string-array name="read_theme_entry_values" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
<declare-styleable name="SubsamplingScaleImageView">
<attr name="src" format="reference" />
<attr name="assetName" format="string" />
+23
View File
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2022 Tarsin Norbin
~
~ This file is part of EhViewer
~
~ EhViewer is free software: you can redistribute it and/or modify it
~ under the terms of the GNU GeneralPublic License as published
~ by the Free Software Foundation,either version 3 of the License, or
~ (at your option) any later version.
~
~ EhViewer is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License along with EhViewer.
~ If not, see <https://www.gnu.org/licenses/>.
-->
<resources>
<bool name="tag_translatable">false</bool>
</resources>
-34
View File
@@ -401,8 +401,6 @@
<string name="settings_u_config_summary">Settings on EHentai website</string>
<string name="settings_my_tags">My tags</string>
<string name="settings_my_tags_summary">My tags on EHentai website</string>
<string name="settings_eh_theme_light">Light</string>
<string name="settings_eh_theme_dark">Dark</string>
<string name="settings_eh_gallery_site">Gallery site</string>
<string name="settings_eh_launch_page">Launch page</string>
<string name="settings_eh_list_mode">List mode</string>
@@ -430,37 +428,7 @@
<string name="settings_eh_filter">Block gallery</string>
<string name="settings_eh_filter_summary">Block gallery by title, uploader and tags</string>
<string name="settings_read">Read</string>
<string name="settings_read_screen_rotation">Screen orientation</string>
<string name="settings_read_screen_rotation_default">Default</string>
<string name="settings_read_screen_rotation_portrait">Portrait</string>
<string name="settings_read_screen_rotation_landscape">Landscape</string>
<string name="settings_read_screen_rotation_sensor">Auto rotate</string>
<string name="settings_read_reading_direction">Reading direction</string>
<string name="settings_read_reading_direction_left_to_right">Left to right</string>
<string name="settings_read_reading_direction_right_to_Left">Right to left</string>
<string name="settings_read_reading_direction_top_to_bottom">Top to bottom</string>
<string name="settings_read_page_scaling">Page scaling</string>
<string name="settings_read_page_scaling_actual_size">Actual size</string>
<string name="settings_read_page_scaling_fit_to_width">Fit to width</string>
<string name="settings_read_page_scaling_fit_to_height">Fit to height</string>
<string name="settings_read_page_scaling_fit_to_screen">Fit to screen</string>
<string name="settings_read_page_scaling_fixed_scale">Fixed scale</string>
<string name="settings_read_start_position">Start position</string>
<string name="settings_read_start_position_top_left">Top left</string>
<string name="settings_read_start_position_top_right">Top right</string>
<string name="settings_read_start_position_bottom_left">Bottom left</string>
<string name="settings_read_start_position_bottom_right">Bottom right</string>
<string name="settings_read_start_position_center">Center</string>
<string name="settings_read_keep_screen_on">Keep screen on</string>
<string name="settings_read_show_clock">Show clock</string>
<string name="settings_read_show_progress">Show progress</string>
<string name="settings_read_show_battery">Show battery</string>
<string name="settings_read_show_page_interval">Show page interval</string>
<string name="settings_read_volume_page">Use volume key to turn pages</string>
<string name="settings_read_reading_fullscreen">Fullscreen</string>
<string name="settings_read_custom_screen_lightness">Custom screen lightness</string>
<string name="settings_read_screen_lightness">Screen lightness</string>
<string name="settings_read_reverse_volume">Reverse volume key</string>
<string name="settings_download">Download</string>
@@ -649,8 +617,6 @@
<string name="from_clipboard">From clipboard</string>
<string name="from_clipboard_error">No cookies found in clipboard.</string>
<string name="delete_search_history">Delete \"%s\" from search history?</string>
<string name="read_theme">Color theme</string>
<string name="follow_app">Follow app</string>
<string name="action_add_tag">Add tag</string>
<string name="action_add_tag_tip">Enter new tags, separated with comma</string>
<string name="comment_user_uploader">%s (Uploader)</string>
+2 -2
View File
@@ -46,19 +46,19 @@
<rikka.preference.SimpleMenuPreference
android:defaultValue="320"
android:key="read_cache_size"
android:summary="%s"
android:title="@string/settings_advanced_read_cache_size"
app:entries="@array/read_cache_size_entries"
app:entryValues="@array/read_cache_size_entry_values"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<rikka.preference.SimpleMenuPreference
android:defaultValue="system"
android:key="app_language"
android:summary="%s"
android:title="@string/settings_advanced_app_language_title"
app:entries="@array/app_language_entries"
app:entryValues="@array/app_language_entry_values"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<com.hippo.ehviewer.preference.ProxyPreference
+5 -6
View File
@@ -26,10 +26,10 @@
<rikka.preference.SimpleMenuPreference
android:defaultValue="1"
android:key="gallery_site"
android:summary="%s"
android:title="@string/settings_eh_gallery_site"
app:entries="@array/gallery_site_entries"
app:entryValues="@array/gallery_site_entry_values"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<com.hippo.ehviewer.preference.SignInRequiredPreference
@@ -49,8 +49,8 @@
android:entries="@array/night_mode_entries"
android:entryValues="@array/night_mode_values"
android:key="theme"
android:summary="%s"
android:title="@string/dark_theme"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
@@ -61,19 +61,19 @@
<rikka.preference.SimpleMenuPreference
android:defaultValue="0"
android:key="launch_page"
android:summary="%s"
android:title="@string/settings_eh_launch_page"
app:entries="@array/launch_page_entries"
app:entryValues="@array/launch_page_entry_values"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<rikka.preference.SimpleMenuPreference
android:defaultValue="0"
android:key="list_mode"
android:summary="%s"
android:title="@string/settings_eh_list_mode"
app:entries="@array/list_mode_entries"
app:entryValues="@array/list_mode_entry_values"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<SeekBarPreference
@@ -88,10 +88,10 @@
<rikka.preference.SimpleMenuPreference
android:defaultValue="0"
android:key="detail_size"
android:summary="%s"
android:title="@string/settings_eh_detail_size"
app:entries="@array/detail_size_entries"
app:entryValues="@array/detail_size_entry_values"
app:useSimpleSummaryProvider="true"
app:iconSpaceReserved="false" />
<SeekBarPreference
@@ -107,7 +107,6 @@
<rikka.preference.SimpleMenuPreference
android:defaultValue="0"
android:key="thumb_resolution"
android:summary="@string/settings_eh_thumb_resolution_summary"
android:title="@string/settings_eh_thumb_resolution"
app:entries="@array/thumb_resolution_entries"
app:entryValues="@array/thumb_resolution_entry_values"
-129
View File
@@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2016 Hippo Seven
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<rikka.preference.SimpleMenuPreference
android:defaultValue="0"
android:key="screen_rotation"
android:summary="%s"
android:title="@string/settings_read_screen_rotation"
app:entries="@array/screen_rotation_entries"
app:entryValues="@array/screen_rotation_entry_values"
app:iconSpaceReserved="false" />
<rikka.preference.SimpleMenuPreference
android:defaultValue="1"
android:key="reading_direction"
android:summary="%s"
android:title="@string/settings_read_reading_direction"
app:entries="@array/reading_direction_entries"
app:entryValues="@array/reading_direction_entry_values"
app:iconSpaceReserved="false" />
<rikka.preference.SimpleMenuPreference
android:defaultValue="3"
android:key="page_scaling"
android:summary="%s"
android:title="@string/settings_read_page_scaling"
app:entries="@array/page_scaling_entries"
app:entryValues="@array/page_scaling_entry_values"
app:iconSpaceReserved="false" />
<rikka.preference.SimpleMenuPreference
android:defaultValue="1"
android:key="start_position"
android:summary="%s"
android:title="@string/settings_read_start_position"
app:entries="@array/start_position_entries"
app:entryValues="@array/start_position_values"
app:iconSpaceReserved="false" />
<rikka.preference.SimpleMenuPreference
android:defaultValue="1"
android:key="read_theme"
android:summary="%s"
android:title="@string/read_theme"
app:entries="@array/read_theme_entries"
app:entryValues="@array/read_theme_entry_values"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="false"
android:key="keep_screen_on"
android:title="@string/settings_read_keep_screen_on"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="true"
android:key="gallery_show_clock"
android:title="@string/settings_read_show_clock"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="true"
android:key="gallery_show_progress"
android:title="@string/settings_read_show_progress"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="true"
android:key="gallery_show_battery"
android:title="@string/settings_read_show_battery"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="true"
android:key="gallery_show_page_interval"
android:title="@string/settings_read_show_page_interval"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="false"
android:key="volume_page"
android:title="@string/settings_read_volume_page"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="false"
android:dependency="volume_page"
android:key="reserve_volume_page"
android:title="@string/settings_read_reverse_volume"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="true"
android:key="reading_fullscreen"
android:title="@string/settings_read_reading_fullscreen"
app:iconSpaceReserved="false" />
<rikka.material.preference.MaterialSwitchPreference
android:defaultValue="false"
android:key="custom_screen_lightness"
android:title="@string/settings_read_custom_screen_lightness"
app:iconSpaceReserved="false" />
<SeekBarPreference
android:defaultValue="50"
android:dependency="custom_screen_lightness"
android:key="screen_lightness"
android:max="200"
android:title="@string/settings_read_screen_lightness"
app:iconSpaceReserved="false"
app:showSeekBarValue="true" />
</PreferenceScreen>
@@ -21,11 +21,6 @@
android:key="com.hippo.ehviewer.ui.fragment.EhFragment"
android:title="@string/settings_eh" />
<Preference
android:icon="@drawable/v_book_open_primary_x24"
android:key="com.hippo.ehviewer.ui.fragment.ReadFragment"
android:title="@string/settings_read" />
<Preference
android:icon="@drawable/v_download_primary_x24"
android:key="com.hippo.ehviewer.ui.fragment.DownloadFragment"
-347
View File
@@ -1,347 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="646"
height="250"
id="svg8502"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="get-it-on.svg">
<defs
id="defs8504">
<linearGradient
inkscape:collect="always"
id="linearGradient4392">
<stop
style="stop-color:#ffffff;stop-opacity:0.09803922"
offset="0"
id="stop4394" />
<stop
style="stop-color:#ffffff;stop-opacity:0"
offset="1"
id="stop4396" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4392"
id="radialGradient4398"
cx="113"
cy="-12.889574"
fx="113"
fy="-12.889574"
r="59.661892"
gradientTransform="matrix(-4.3416142e-8,1.9610509,-1.9778119,2.8493899e-8,254.50686,78.76343)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4142136"
inkscape:cx="322.4318"
inkscape:cy="148.85197"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="0"
inkscape:window-y="34"
inkscape:window-maximized="1" />
<metadata
id="metadata8507">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Andrew Nayenko</dc:title>
</cc:Agent>
</dc:creator>
<dc:publisher>
<cc:Agent>
<dc:title>https://f-droid.org</dc:title>
</cc:Agent>
</dc:publisher>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-289,-312.36218)">
<rect
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#a6a6a6;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate"
id="rect3007"
width="560"
height="164"
x="332"
y="355.36218"
rx="20"
ry="20" />
<text
sodipodi:linespacing="100%"
id="text3013"
y="402.36697"
x="508.95129"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.39519119px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate"
xml:space="preserve"><tspan
y="402.36697"
x="508.95129"
id="tspan3015"
sodipodi:role="line"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:34.125px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans'">GET IT ON</tspan></text>
<text
xml:space="preserve"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:29.70882034px;line-height:100%;font-family:Rokkitt;-inkscape-font-specification:'Rokkitt Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate"
x="508.21259"
y="489.36108"
id="text5902"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan5904"
x="508.21259"
y="489.36108"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:95px;line-height:100%;font-family:'Roboto Slab';-inkscape-font-specification:'Roboto Slab Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1">F-Droid</tspan></text>
<g
id="g4400"
transform="translate(80.999992,75.999997)">
<g
id="g5012"
transform="matrix(2.6315876,0,0,2.6315749,275.84226,-2346.4746)">
<g
transform="matrix(-1,0,0,1,47.999779,0)"
id="g4179">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4181"
d="m 2.5889342,1006.8622 4.25,5.5"
style="fill:#8ab000;fill-opacity:1;fill-rule:evenodd;stroke:#769616;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:0.29803922;fill-rule:evenodd;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 2.6113281,1005.6094 c -0.4534623,0.012 -0.7616975,0.189 -0.9807462,0.4486 2.0269314,2.4089 2.368401,2.7916 5.1354735,6.2214 1.0195329,1.319 2.0816026,0.6373 1.0620696,-0.6817 l -4.25,-5.5 c -0.2289894,-0.3056 -0.5850813,-0.478 -0.9667969,-0.4883 z"
id="path4183"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#263238;fill-opacity:0.2;fill-rule:evenodd;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 1.6220992,1006.0705 c -0.1238933,0.1479 -0.561176,0.8046 -0.02249,1.5562 l 4.25,5.5 c 1.0195329,1.319 1.1498748,-0.6123 1.1498748,-0.6123 0,0 -3.7344514,-4.51 -5.3773848,-6.4439 z"
id="path4185"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#8ab000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 2.3378905,1005.8443 c -0.438175,0 -0.959862,0.1416 -0.8242183,0.7986 0.103561,0.5016 4.6608262,6.0744 4.6608262,6.0744 1.0195329,1.319 2.4934721,0.6763 1.4739391,-0.6425 l -4.234375,-5.4727 c -0.2602394,-0.29 -0.6085188,-0.7436 -1.076172,-0.7578 z"
id="path4187"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscccc" />
</g>
<g
id="g4955">
<path
style="fill:#8ab000;fill-opacity:1;fill-rule:evenodd;stroke:#769616;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 2.5889342,1006.8622 4.25,5.5"
id="path4945"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path4947"
d="m 2.6113281,1005.6094 c -0.4534623,0.012 -0.7616975,0.189 -0.9807462,0.4486 2.0269314,2.4089 2.368401,2.7916 5.1354735,6.2214 1.0195329,1.319 2.0816026,0.6373 1.0620696,-0.6817 l -4.25,-5.5 c -0.2289894,-0.3056 -0.5850813,-0.478 -0.9667969,-0.4883 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:0.29803922;fill-rule:evenodd;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4951"
d="m 1.6220992,1006.0705 c -0.1238933,0.1479 -0.561176,0.8046 -0.02249,1.5562 l 4.25,5.5 c 1.0195329,1.319 1.1498748,-0.6123 1.1498748,-0.6123 0,0 -3.7344514,-4.51 -5.3773848,-6.4439 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#263238;fill-opacity:0.2;fill-rule:evenodd;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
sodipodi:nodetypes="cscccc"
inkscape:connector-curvature="0"
id="path4925"
d="m 2.3378905,1005.8443 c -0.438175,0 -0.959862,0.1416 -0.8242183,0.7986 0.103561,0.5016 4.6608262,6.0744 4.6608262,6.0744 1.0195329,1.319 2.4934721,0.6763 1.4739391,-0.6425 l -4.234375,-5.4727 c -0.2602394,-0.29 -0.6085188,-0.7436 -1.076172,-0.7578 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#8ab000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
<g
id="g4967"
transform="translate(42,0)">
<rect
ry="3"
rx="3"
y="1010.3596"
x="-37"
height="12.92002"
width="38"
id="rect4144"
style="opacity:1;fill:#aeea00;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#263238;fill-opacity:0.2;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4961"
width="38"
height="10"
x="-37"
y="1013.2795"
rx="3"
ry="3" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:0.29803922;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4963"
width="38"
height="10"
x="-37"
y="1010.3622"
rx="3"
ry="3" />
<rect
style="opacity:1;fill:#aeea00;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4965"
width="38"
height="10.640781"
x="-37"
y="1011.5002"
rx="3"
ry="2.455565" />
</g>
<g
transform="translate(0,-0.10259092)"
id="g4979">
<rect
ry="3"
rx="3"
y="1024.5221"
x="5"
height="25.84004"
width="38"
id="rect4146"
style="opacity:1;fill:#1976d2;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<rect
style="opacity:1;fill:#263238;fill-opacity:0.2;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4973"
width="38"
height="13"
x="5"
y="1037.3622"
rx="3"
ry="3" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:0.2;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4975"
width="38"
height="13"
x="5"
y="1024.4421"
rx="3"
ry="3" />
<rect
style="opacity:1;fill:#1976d2;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:3;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4977"
width="38"
height="23.560036"
x="5"
y="1025.6621"
rx="3"
ry="2.7184658" />
</g>
<g
id="g4211"
transform="translate(0,1013.3622)">
<path
inkscape:connector-curvature="0"
id="path4161"
d="m 24,17.75 c -2.880662,0 -5.319789,1.984685 -6.033203,4.650391 l 3.212891,0 C 21.734004,21.415044 22.774798,20.75 24,20.75 c 1.812692,0 3.25,1.437308 3.25,3.25 0,1.812693 -1.437308,3.25 -3.25,3.25 -1.307381,0 -2.411251,-0.75269 -2.929688,-1.849609 l -3.154296,0 C 18.558263,28.166146 21.04791,30.25 24,30.25 c 3.434013,0 6.25,-2.815987 6.25,-6.25 0,-3.434012 -2.815987,-6.25 -6.25,-6.25 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#0d47a1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<circle
r="9.5500002"
cy="24"
cx="24"
id="path4209"
style="opacity:1;fill:none;fill-opacity:0.40392157;stroke:#0d47a1;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
transform="translate(0,0.50001738)"
id="g4989">
<ellipse
ry="3.875"
rx="3.375"
style="opacity:1;fill:#263238;fill-opacity:0.2;stroke:none;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.69721117"
id="circle4985"
cx="14.375"
cy="1016.4872" />
<circle
r="3.375"
cy="1016.9872"
cx="14.375"
id="path4859"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.69721117" />
</g>
<g
id="g4201"
transform="translate(19.5,0.50001738)">
<ellipse
cy="1016.4872"
cx="14.375"
id="ellipse4175"
style="opacity:1;fill:#263238;fill-opacity:0.2;stroke:none;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.69721117"
rx="3.375"
ry="3.875" />
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.89999998;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.69721117"
id="circle4177"
cx="14.375"
cy="1016.9872"
r="3.375" />
</g>
</g>
<path
inkscape:connector-curvature="0"
id="path4286"
d="m 282.71484,299.83484 a 3.2898056,3.2898056 0 0 0 -2.66211,5.33593 l 9.47461,12.26172 C 289.19237,318.31001 289,319.25869 289,320.25671 l 0,18.21094 c 0,4.37367 3.52083,7.89453 7.89453,7.89453 l 84.21094,0 c 4.3737,0 7.89453,-3.52086 7.89453,-7.89453 l 0,-18.21094 c 0,-0.99858 -0.19005,-1.94824 -0.52539,-2.82617 l 9.47266,-12.25977 a 3.2898056,3.2898056 0 0 0 -2.4336,-5.33398 3.2898056,3.2898056 0 0 0 -2.77148,1.31055 l -9.01367,11.66601 c -0.82093,-0.28771 -1.70144,-0.45117 -2.62305,-0.45117 l -84.21094,0 c -0.92137,0 -1.80035,0.1636 -2.62109,0.45117 l -9.01563,-11.66601 a 3.2898056,3.2898056 0 0 0 -2.54297,-1.3125 z m 14.17969,49.52734 c -4.3737,0 -7.89453,3.52085 -7.89453,7.89453 l 0,52.21094 c 0,4.37368 3.52083,7.89453 7.89453,7.89453 l 84.21094,0 c 4.3737,0 7.89453,-3.52085 7.89453,-7.89453 l 0,-52.21094 c 0,-4.37368 -3.52083,-7.89453 -7.89453,-7.89453 l -84.21094,0 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#radialGradient4398);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:6.57895327;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 24 KiB

-55
View File
@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="646" height="250" id="svg8502" version="1.1" inkscape:version="0.91 r13725" sodipodi:docname="get-it-on-github.svg" inkscape:export-filename="/home/nixdorf/Lokaler Speicher/Build/andOTP/assets/badges/get-it-on-github.png" inkscape:export-xdpi="90" inkscape:export-ydpi="90">
<defs id="defs8504" />
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.50000001" inkscape:cx="-223.13537" inkscape:cy="546.37524" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="true" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" fit-margin-bottom="0" inkscape:window-width="1920" inkscape:window-height="1021" inkscape:window-x="0" inkscape:window-y="31" inkscape:window-maximized="1" />
<metadata id="metadata8507">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:creator>
<cc:Agent>
<dc:title>Andrew Nayenko</dc:title>
</cc:Agent>
</dc:creator>
<dc:publisher>
<cc:Agent>
<dc:title>https://f-droid.org</dc:title>
</cc:Agent>
</dc:publisher>
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
<dc:contributor>
<cc:Agent>
<dc:title />
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g inkscape:label="Layer 1" inkscape:groupmode="layer" id="layer1" transform="translate(-289,-312.36218)">
<rect style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#a6a6a6;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker:none;enable-background:accumulate" id="rect3007" width="560" height="164" x="332" y="355.36218" rx="20" ry="20" />
<text sodipodi:linespacing="100%" id="text3013" y="402.36697" x="508.95129" style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.39519119px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate" xml:space="preserve"><tspan y="402.36697" x="508.95129" id="tspan3015" sodipodi:role="line" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:34.125px;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans'">GET IT ON</tspan></text>
<text xml:space="preserve" style="color:black;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:29.70882034px;line-height:100%;font-family:Rokkitt;-inkscape-font-specification:'Rokkitt Bold';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate" x="508.21259" y="489.36108" id="text5902" sodipodi:linespacing="100%"><tspan sodipodi:role="line" id="tspan5904" x="508.21259" y="489.36108" style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:87.5px;line-height:100%;font-family:'Roboto Slab';-inkscape-font-specification:'Roboto Slab Bold';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:white;fill-opacity:1">GitHub</tspan></text>
<g transform="matrix(1.0017681,0,0,1.0017681,68.770756,92.660249)" id="g5136">
<path style="fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none" d="m 350.60937,282.4375 c -33.34765,0 -60.38671,27.03516 -60.38671,60.38672 0,26.67969 17.30078,49.3164 41.29687,57.30078 3.01563,0.55859 4.125,-1.30859 4.125,-2.90625 0,-1.4375 -0.0547,-6.19531 -0.082,-11.24219 -16.80078,3.65235 -20.34375,-7.125 -20.34375,-7.125 -2.75,-6.98047 -6.70703,-8.83594 -6.70703,-8.83594 -5.48047,-3.74609 0.41406,-3.67187 0.41406,-3.67187 6.0625,0.42578 9.25781,6.22266 9.25781,6.22266 5.38282,9.23437 14.125,6.5664 17.57032,5.02343 0.54296,-3.90234 2.10937,-6.57031 3.83593,-8.07812 -13.41406,-1.52735 -27.51562,-6.70313 -27.51562,-29.84375 0,-6.59375 2.35937,-11.98047 6.22265,-16.20703 -0.625,-1.52344 -2.6914,-7.66407 0.58594,-15.98047 0,0 5.07031,-1.625 16.60938,6.1875 4.82031,-1.33594 9.98437,-2.00781 15.11718,-2.03125 5.13282,0.0234 10.30079,0.69531 15.12891,2.03125 11.52344,-7.8125 16.58984,-6.1875 16.58984,-6.1875 3.28516,8.3164 1.21875,14.45703 0.58985,15.98047 3.87109,4.22656 6.21484,9.61328 6.21484,16.20703 0,23.19531 -14.125,28.30078 -27.57422,29.79687 2.16797,1.875 4.09766,5.55078 4.09766,11.1836 0,8.07812 -0.0703,14.58203 -0.0703,16.57031 0,1.60937 1.08593,3.49219 4.14843,2.89844 23.98047,-7.9961 41.26172,-30.6211 41.26172,-57.29297 0,-33.35156 -27.03515,-60.38672 -60.38672,-60.38672" id="path4937" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 313.09375,369.14062 c -0.13281,0.30079 -0.60547,0.38672 -1.03516,0.1836 -0.4375,-0.19922 -0.68359,-0.60547 -0.54297,-0.91016 0.12891,-0.30859 0.60157,-0.39062 1.03907,-0.1875 0.4414,0.19922 0.6914,0.61328 0.53906,0.91406" id="path4939" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 315.53906,371.86719 c -0.28906,0.26562 -0.85156,0.14453 -1.23437,-0.27735 -0.39453,-0.42187 -0.46875,-0.98437 -0.17578,-1.25781 0.29687,-0.26562 0.84375,-0.14062 1.23828,0.28125 0.39453,0.42578 0.47265,0.98438 0.17187,1.25391" id="path4941" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 317.92187,375.34375 c -0.37109,0.25781 -0.97656,0.0156 -1.35156,-0.51953 -0.37109,-0.53906 -0.37109,-1.17969 0.008,-1.4375 0.375,-0.25781 0.97266,-0.0274 1.35157,0.5039 0.36718,0.54688 0.36718,1.19141 -0.008,1.45313" id="path4943" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 321.18359,378.70312 c -0.33203,0.36719 -1.03906,0.26954 -1.55468,-0.23046 -0.52735,-0.48438 -0.67579,-1.17579 -0.34375,-1.54297 0.33593,-0.36328 1.04687,-0.26172 1.5664,0.23047 0.52344,0.48828 0.6836,1.18359 0.33203,1.54296" id="path4945-3" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 325.68359,380.65625 c -0.14843,0.47266 -0.82812,0.6875 -1.51172,0.48828 -0.68359,-0.20703 -1.1289,-0.76172 -0.99218,-1.24219 0.14453,-0.47265 0.82422,-0.69922 1.51562,-0.48437 0.67969,0.20703 1.12891,0.75781 0.98828,1.23828" id="path4947-6" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 330.625,381.01953 c 0.0156,0.49609 -0.5625,0.91016 -1.28125,0.91797 -0.72266,0.0156 -1.30859,-0.38672 -1.31641,-0.875 0,-0.50391 0.57032,-0.91406 1.28907,-0.92578 0.71875,-0.0156 1.30859,0.38672 1.30859,0.88281" id="path4949" inkscape:connector-curvature="0" />
<path style="fill:white;fill-opacity:1;fill-rule:nonzero;stroke:none" d="m 335.22266,380.23437 c 0.0859,0.48829 -0.41407,0.98438 -1.125,1.11719 -0.70313,0.12891 -1.35157,-0.17187 -1.44141,-0.65234 -0.0859,-0.5 0.42187,-0.9961 1.12109,-1.125 0.71485,-0.125 1.35547,0.16797 1.44532,0.66015" id="path4951-7" inkscape:connector-curvature="0" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.5 KiB

-10
View File
@@ -1,10 +0,0 @@
<svg width="108" height="108" viewBox="0 0 108 108" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="108" height="108" rx="10" fill="white"/>
<path d="M32 31H55" stroke="#FBBD06" stroke-width="8" stroke-linecap="round"/>
<path d="M32 76H44" stroke="#FBBD06" stroke-width="8" stroke-linecap="round"/>
<line x1="32" y1="31" x2="32" y2="76" stroke="#35AA53" stroke-width="8" stroke-linecap="round"/>
<line x1="32" y1="53" x2="73" y2="53" stroke="#FBBD06" stroke-width="8" stroke-linecap="round"/>
<line x1="73" y1="53" x2="73" y2="76" stroke="#4586F3" stroke-width="8" stroke-linecap="round"/>
<path d="M55 43L55 76" stroke="#EB4334" stroke-width="8" stroke-linecap="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M36 57H32C29.7909 57 28 55.2091 28 53C28 50.7909 29.7909 49 32 49H36V57Z" fill="#FBBD06"/>
</svg>

Before

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 MiB

+4 -4
View File
@@ -11,7 +11,7 @@
</p>
<h1 align="center">
<img src="../../art/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<br>EhViewer<br>
</h1>
@@ -66,12 +66,12 @@ with Material Design 3 and Dynamic Color Support
# Download
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="../../art/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="../../art/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
# Screenshot
![screenshot-01](../../art/screenshot-01.png)
![screenshot-02](../../art/screenshot-02.png)
![screenshot-01](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-01.png)
![screenshot-02](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-02.png)
# Thanks
+4 -4
View File
@@ -11,7 +11,7 @@
</p>
<h1 align="center">
<img src="../../art/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<br>EhViewer<br>
</h1>
@@ -66,12 +66,12 @@
# 下载
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="../../art/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="../../art/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
# 截图
![screenshot-01](../../art/screenshot-01.png)
![screenshot-02](../../art/screenshot-02.png)
![screenshot-01](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-01.png)
![screenshot-02](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-02.png)
# 感谢
+4 -4
View File
@@ -11,7 +11,7 @@
</p>
<h1 align="center">
<img src="../../art/launcher_icon-web.svg" width="200">
<img src="https://github.com/Ehviewer-Overhauled/Art/blob/master/launcher_icon-web.svg" width="200">
<br>EhViewer<br>
</h1>
@@ -66,12 +66,12 @@
# 下載
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="../../art/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="../../art/get-it-on-fdroid.svg" width="200px"/></a>
<a href="https://github.com/Ehviewer-Overhauled/Ehviewer/releases"><img alt="Get it on GitHub" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-github.svg" width="200px"/></a> <a href="https://github.com/Ehviewer-Overhauled/fdroid-repo"><img alt="Git it on F-Droid" src="https://github.com/Ehviewer-Overhauled/Art/blob/master/get-it-on-fdroid.svg" width="200px"/></a>
# 截圖
![screenshot-01](../../art/screenshot-01.png)
![screenshot-02](../../art/screenshot-02.png)
![screenshot-01](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-01.png)
![screenshot-02](https://github.com/Ehviewer-Overhauled/Art/blob/master/screenshot-02.png)
# 感謝
-8
View File
@@ -12,14 +12,6 @@ dependencyResolutionManagement {
mavenCentral()
maven { url "https://jcenter.bintray.com" }
maven { url "https://jitpack.io" }
maven {
name = "MaterialSnapshots"
url = uri("https://maven.pkg.github.com/material-components/material-components-android")
credentials {
username = "nullArrayList"
password = "ghp_" + "TTLrOZAWR" + "MlbqMF" + "zwJNdaNON" + "EDDRM22DCHSL" // This github account has nothing and this token only have "read packages" permission. So guys, don't try to do bad things
}
}
}
}
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")