Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ce823e9b20 | ||
|
|
0caa5b1a3b | ||
|
|
9edea5d584 | ||
|
|
9a773aeb39 | ||
|
|
9fd3196bb1 | ||
|
|
7580572874 | ||
|
|
06acc620f4 | ||
|
|
367358d277 | ||
|
|
d61df599e8 | ||
|
|
989a0a01c1 | ||
|
|
12108645e9 | ||
|
|
4910ec194d | ||
|
|
f730f43945 |
No files matched your search
@@ -34,8 +34,8 @@ android {
|
|||||||
applicationId = "moe.tarsin.ehviewer"
|
applicationId = "moe.tarsin.ehviewer"
|
||||||
minSdk = 28
|
minSdk = 28
|
||||||
targetSdk = 33
|
targetSdk = 33
|
||||||
versionCode = 180032
|
versionCode = 180034
|
||||||
versionName = "1.8.6.0"
|
versionName = "1.8.6.2"
|
||||||
resourceConfigurations.addAll(
|
resourceConfigurations.addAll(
|
||||||
listOf(
|
listOf(
|
||||||
"zh",
|
"zh",
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".ui.login.LoginActivity"
|
android:name=".ui.login.LoginActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:theme="@style/AppTheme"
|
android:launchMode="singleTask"
|
||||||
android:windowSoftInputMode="adjustResize"/>
|
android:windowSoftInputMode="adjustResize"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
|
|||||||
@@ -91,7 +91,8 @@ object GalleryDetailParser {
|
|||||||
// Error info
|
// Error info
|
||||||
PATTERN_ERROR.find(body)?.run { throw EhException(groupValues[1]) }
|
PATTERN_ERROR.find(body)?.run { throw EhException(groupValues[1]) }
|
||||||
val galleryDetail = GalleryDetail()
|
val galleryDetail = GalleryDetail()
|
||||||
val document = Jsoup.parse(body)
|
// Temporary workaround, see https://github.com/jhy/jsoup/issues/1850
|
||||||
|
val document = Jsoup.parse(body.replace("del>", "s>"))
|
||||||
parseDetail(galleryDetail, document, body)
|
parseDetail(galleryDetail, document, body)
|
||||||
galleryDetail.tags = parseTagGroups(document)
|
galleryDetail.tags = parseTagGroups(document)
|
||||||
galleryDetail.comments = parseComments(document)
|
galleryDetail.comments = parseComments(document)
|
||||||
@@ -376,15 +377,15 @@ object GalleryDetailParser {
|
|||||||
}
|
}
|
||||||
// time
|
// time
|
||||||
val c3 = JsoupUtils.getElementByClass(element, "c3")
|
val c3 = JsoupUtils.getElementByClass(element, "c3")
|
||||||
var temp = c3!!.ownText()
|
val temp = c3!!.ownText()
|
||||||
if (temp.endsWith(':')) {
|
val time = if (temp.endsWith(':')) {
|
||||||
temp = temp.substring("Posted on ".length, temp.length - " by:".length)
|
|
||||||
// user
|
// user
|
||||||
comment.user = c3.child(0).text()
|
comment.user = c3.child(0).text()
|
||||||
|
temp.substring("Posted on ".length, temp.length - " by:".length)
|
||||||
} else {
|
} else {
|
||||||
temp = temp.substring("Posted on ".length)
|
temp.substring("Posted on ".length)
|
||||||
}
|
}
|
||||||
comment.time = Instant.from(WEB_COMMENT_DATE_FORMAT.parse(temp)).toEpochMilli()
|
comment.time = Instant.from(WEB_COMMENT_DATE_FORMAT.parse(time)).toEpochMilli()
|
||||||
// comment
|
// comment
|
||||||
val c6 = JsoupUtils.getElementByClass(element, "c6")
|
val c6 = JsoupUtils.getElementByClass(element, "c6")
|
||||||
// fix underline support
|
// fix underline support
|
||||||
@@ -407,7 +408,7 @@ object GalleryDetailParser {
|
|||||||
val e = c8.children().first()
|
val e = c8.children().first()
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
comment.lastEdited =
|
comment.lastEdited =
|
||||||
Instant.from(WEB_COMMENT_DATE_FORMAT.parse(temp)).toEpochMilli()
|
Instant.from(WEB_COMMENT_DATE_FORMAT.parse(e.text())).toEpochMilli()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
comment
|
comment
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import com.hippo.yorozuya.FileUtils
|
|||||||
import com.hippo.yorozuya.MathUtils
|
import com.hippo.yorozuya.MathUtils
|
||||||
import kotlinx.coroutines.currentCoroutineContext
|
import kotlinx.coroutines.currentCoroutineContext
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
|
import moe.tarsin.coroutines.runSuspendCatching
|
||||||
import okhttp3.executeAsync
|
import okhttp3.executeAsync
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -194,7 +195,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
|||||||
return receivedSize
|
return receivedSize
|
||||||
}
|
}
|
||||||
|
|
||||||
findDownloadFileForIndex(index, extension)?.runCatching {
|
findDownloadFileForIndex(index, extension)?.runSuspendCatching {
|
||||||
openOutputStream().use { outputStream ->
|
openOutputStream().use { outputStream ->
|
||||||
(outputStream as FileOutputStream).channel.use { return doSave(it) == length }
|
(outputStream as FileOutputStream).channel.use { return doSave(it) == length }
|
||||||
}
|
}
|
||||||
@@ -208,7 +209,7 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
|
|||||||
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
val key = EhCacheKeyFactory.getImageKey(mGid, index)
|
||||||
val editor = sCache.edit(key) ?: return false
|
val editor = sCache.edit(key) ?: return false
|
||||||
var received: Long = 0
|
var received: Long = 0
|
||||||
runCatching {
|
runSuspendCatching {
|
||||||
editor.metadata.toFile().writeText(extension)
|
editor.metadata.toFile().writeText(extension)
|
||||||
editor.data.toFile().outputStream().use { outputStream ->
|
editor.data.toFile().outputStream().use { outputStream ->
|
||||||
outputStream.channel.use { received = doSave(it) }
|
outputStream.channel.use { received = doSave(it) }
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ public final class SpiderQueen implements Runnable {
|
|||||||
request(index, false);
|
request(index, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getPageState(int index) {
|
public int getPageState(int index) {
|
||||||
synchronized (mPageStateLock) {
|
synchronized (mPageStateLock) {
|
||||||
if (mPageStateArray != null && index >= 0 && index < mPageStateArray.length) {
|
if (mPageStateArray != null && index >= 0 && index < mPageStateArray.length) {
|
||||||
return mPageStateArray[index];
|
return mPageStateArray[index];
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ import com.hippo.ehviewer.spider.SpiderQueen.NETWORK_ERROR
|
|||||||
import com.hippo.ehviewer.spider.SpiderQueen.PTOKEN_FAILED_MESSAGE
|
import com.hippo.ehviewer.spider.SpiderQueen.PTOKEN_FAILED_MESSAGE
|
||||||
import com.hippo.ehviewer.spider.SpiderQueen.STATE_FAILED
|
import com.hippo.ehviewer.spider.SpiderQueen.STATE_FAILED
|
||||||
import com.hippo.ehviewer.spider.SpiderQueen.STATE_FINISHED
|
import com.hippo.ehviewer.spider.SpiderQueen.STATE_FINISHED
|
||||||
|
import com.hippo.ehviewer.spider.SpiderQueen.STATE_DOWNLOADING
|
||||||
import com.hippo.image.Image.Companion.decode
|
import com.hippo.image.Image.Companion.decode
|
||||||
import com.hippo.util.ExceptionUtils
|
import com.hippo.util.ExceptionUtils
|
||||||
import com.hippo.yorozuya.StringUtils
|
import eu.kanade.tachiyomi.util.lang.launchNonCancellable
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@@ -27,7 +28,6 @@ import kotlinx.coroutines.sync.Semaphore
|
|||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.sync.withPermit
|
import kotlinx.coroutines.sync.withPermit
|
||||||
import moe.tarsin.coroutines.runSuspendCatching
|
import moe.tarsin.coroutines.runSuspendCatching
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
||||||
private val spiderDen
|
private val spiderDen
|
||||||
@@ -42,8 +42,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
private var isDownloadMode = false
|
private var isDownloadMode = false
|
||||||
private val size
|
private val size
|
||||||
get() = queen.size()
|
get() = queen.size()
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext = Dispatchers.IO + Job()
|
||||||
get() = Dispatchers.IO + Job()
|
|
||||||
|
|
||||||
fun cancelDecode(index: Int) {
|
fun cancelDecode(index: Int) {
|
||||||
decoder.cancel(index)
|
decoder.cancel(index)
|
||||||
@@ -80,6 +79,15 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
mSemaphore.withPermit {
|
mSemaphore.withPermit {
|
||||||
doInJob(index, force)
|
doInJob(index, force)
|
||||||
}
|
}
|
||||||
|
}.apply {
|
||||||
|
invokeOnCompletion {
|
||||||
|
if (queen.getPageState(index) == STATE_DOWNLOADING) {
|
||||||
|
Log.d(DEBUG_TAG, "Download image cancelled $index")
|
||||||
|
launchNonCancellable {
|
||||||
|
spiderDen.remove(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,7 +108,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
?: queen.getPTokenFromInternet(index)
|
?: queen.getPTokenFromInternet(index)
|
||||||
?: queen.getPTokenFromMultiPageViewer(index)
|
?: queen.getPTokenFromMultiPageViewer(index)
|
||||||
}
|
}
|
||||||
queen.updatePageState(index, SpiderQueen.STATE_DOWNLOADING)
|
queen.updatePageState(index, STATE_DOWNLOADING)
|
||||||
if (!force && index in spiderDen) {
|
if (!force && index in spiderDen) {
|
||||||
return queen.updatePageState(index, STATE_FINISHED)
|
return queen.updatePageState(index, STATE_FINISHED)
|
||||||
}
|
}
|
||||||
@@ -149,7 +157,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
}
|
}
|
||||||
runSuspendCatching {
|
runSuspendCatching {
|
||||||
getGalleryPage(pageUrl, spiderInfo.gid, spiderInfo.token).also {
|
getGalleryPage(pageUrl, spiderInfo.gid, spiderInfo.token).also {
|
||||||
if (StringUtils.endsWith(it.imageUrl, URL_509_SUFFIX_ARRAY)) {
|
if (check509(it.imageUrl)) {
|
||||||
// Get 509
|
// Get 509
|
||||||
queen.notifyGet509(index)
|
queen.notifyGet509(index)
|
||||||
error = ERROR_509
|
error = ERROR_509
|
||||||
@@ -200,7 +208,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
localShowKey,
|
localShowKey,
|
||||||
previousPToken
|
previousPToken
|
||||||
).also {
|
).also {
|
||||||
if (StringUtils.endsWith(it.imageUrl, URL_509_SUFFIX_ARRAY)) {
|
if (check509(it.imageUrl)) {
|
||||||
// Get 509
|
// Get 509
|
||||||
queen.notifyGet509(index)
|
queen.notifyGet509(index)
|
||||||
error = ERROR_509
|
error = ERROR_509
|
||||||
@@ -270,6 +278,7 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
}.onFailure {
|
}.onFailure {
|
||||||
it.printStackTrace()
|
it.printStackTrace()
|
||||||
error = NETWORK_ERROR
|
error = NETWORK_ERROR
|
||||||
|
forceHtml = true
|
||||||
}
|
}
|
||||||
Log.d(DEBUG_TAG, "End download image $index")
|
Log.d(DEBUG_TAG, "End download image $index")
|
||||||
}
|
}
|
||||||
@@ -278,10 +287,13 @@ class SpiderQueenWorker(private val queen: SpiderQueen) : CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val URL_509_SUFFIX_ARRAY = arrayOf(
|
private val URL_509_ARRAY = arrayOf(
|
||||||
"/509.gif",
|
"https://ehgt.org/g/509.gif",
|
||||||
"/509s.gif"
|
"https://ehgt.org/g/509s.gif",
|
||||||
|
"https://exhentai.org/img/509.gif",
|
||||||
|
"https://exhentai.org/img/509s.gif"
|
||||||
)
|
)
|
||||||
|
private fun check509(url: String) = url in URL_509_ARRAY
|
||||||
|
|
||||||
private const val DEBUG_TAG = "SpiderQueenWorker"
|
private const val DEBUG_TAG = "SpiderQueenWorker"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ import java.io.OutputStream
|
|||||||
class MainActivity : EhActivity() {
|
class MainActivity : EhActivity() {
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
private lateinit var navController: NavController
|
private lateinit var navController: NavController
|
||||||
private lateinit var connectivityManager: ConnectivityManager
|
private val connectivityManager by lazy { getSystemService<ConnectivityManager>()!! }
|
||||||
private val availableNetworks: MutableList<Network> = mutableListOf()
|
private val availableNetworks = mutableListOf<Network>()
|
||||||
|
|
||||||
private fun saveImageToTempFile(uri: Uri): File? {
|
private fun saveImageToTempFile(uri: Uri): File? {
|
||||||
val src = ImageDecoder.createSource(contentResolver, uri)
|
val src = ImageDecoder.createSource(contentResolver, uri)
|
||||||
@@ -223,7 +223,6 @@ class MainActivity : EhActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
connectivityManager = getSystemService()!!
|
|
||||||
if (Settings.getDF() && Settings.getBypassVpn()) {
|
if (Settings.getDF() && Settings.getBypassVpn()) {
|
||||||
bypassVpn()
|
bypassVpn()
|
||||||
}
|
}
|
||||||
@@ -233,13 +232,7 @@ class MainActivity : EhActivity() {
|
|||||||
val navHostFragment =
|
val navHostFragment =
|
||||||
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
|
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
|
||||||
navController = navHostFragment.navController
|
navController = navHostFragment.navController
|
||||||
if (EhUtils.needSignedIn()) {
|
if (!EhUtils.needSignedIn()) setNavGraph()
|
||||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
|
||||||
setNavGraph()
|
|
||||||
}.launch(Intent(this, LoginActivity::class.java))
|
|
||||||
} else {
|
|
||||||
setNavGraph()
|
|
||||||
}
|
|
||||||
binding.drawView.addDrawerListener(mDrawerOnBackPressedCallback)
|
binding.drawView.addDrawerListener(mDrawerOnBackPressedCallback)
|
||||||
binding.navView.setupWithNavController(navController)
|
binding.navView.setupWithNavController(navController)
|
||||||
|
|
||||||
@@ -371,7 +364,19 @@ class MainActivity : EhActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val loginLauncher =
|
||||||
|
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
|
if (availableNetworks.isNotEmpty()) {
|
||||||
|
connectivityManager.bindProcessToNetwork(availableNetworks.last())
|
||||||
|
}
|
||||||
|
setNavGraph()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
if (EhUtils.needSignedIn()) {
|
||||||
|
connectivityManager.bindProcessToNetwork(null)
|
||||||
|
loginLauncher.launch(Intent(this, LoginActivity::class.java))
|
||||||
|
}
|
||||||
super.onResume()
|
super.onResume()
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
delay(100)
|
delay(100)
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ import com.hippo.ehviewer.client.EhRequest
|
|||||||
import com.hippo.ehviewer.client.EhUtils
|
import com.hippo.ehviewer.client.EhUtils
|
||||||
import com.hippo.ehviewer.client.data.GalleryInfo
|
import com.hippo.ehviewer.client.data.GalleryInfo
|
||||||
import com.hippo.ehviewer.client.data.ListUrlBuilder
|
import com.hippo.ehviewer.client.data.ListUrlBuilder
|
||||||
|
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_NORMAL
|
||||||
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_SUBSCRIPTION
|
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_SUBSCRIPTION
|
||||||
|
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_TAG
|
||||||
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_TOPLIST
|
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_TOPLIST
|
||||||
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_WHATS_HOT
|
import com.hippo.ehviewer.client.data.ListUrlBuilder.Companion.MODE_WHATS_HOT
|
||||||
import com.hippo.ehviewer.client.exception.EhException
|
import com.hippo.ehviewer.client.exception.EhException
|
||||||
@@ -98,13 +100,14 @@ import com.hippo.widget.FabLayout
|
|||||||
import com.hippo.widget.FabLayout.OnClickFabListener
|
import com.hippo.widget.FabLayout.OnClickFabListener
|
||||||
import com.hippo.widget.FabLayout.OnExpandListener
|
import com.hippo.widget.FabLayout.OnExpandListener
|
||||||
import com.hippo.yorozuya.AnimationUtils
|
import com.hippo.yorozuya.AnimationUtils
|
||||||
import com.hippo.yorozuya.MathUtils
|
|
||||||
import com.hippo.yorozuya.SimpleAnimatorListener
|
import com.hippo.yorozuya.SimpleAnimatorListener
|
||||||
import com.hippo.yorozuya.StringUtils
|
import com.hippo.yorozuya.StringUtils
|
||||||
import com.hippo.yorozuya.ViewUtils
|
import com.hippo.yorozuya.ViewUtils
|
||||||
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||||
import eu.kanade.tachiyomi.util.lang.launchIO
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import rikka.core.res.resolveColor
|
import rikka.core.res.resolveColor
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
@@ -216,6 +219,13 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
|
|
||||||
else -> throw IllegalStateException("Wrong KEY_ACTION:${args?.getString(KEY_ACTION)} when handle args!")
|
else -> throw IllegalStateException("Wrong KEY_ACTION:${args?.getString(KEY_ACTION)} when handle args!")
|
||||||
}
|
}
|
||||||
|
val goto = args?.getString(KEY_GOTO)
|
||||||
|
goto?.let {
|
||||||
|
lifecycleScope.launchUI {
|
||||||
|
delay(100)
|
||||||
|
mHelper?.goTo(it, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@@ -288,25 +298,6 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapTagKeyword(keyword: String?): String {
|
|
||||||
var keyword = keyword
|
|
||||||
keyword = keyword!!.trim { it <= ' ' }
|
|
||||||
val index1 = keyword.indexOf(':')
|
|
||||||
if (index1 == -1 || index1 >= keyword.length - 1) {
|
|
||||||
// Can't find :, or : is the last char
|
|
||||||
return keyword
|
|
||||||
}
|
|
||||||
if (keyword[index1 + 1] == '"') {
|
|
||||||
// The char after : is ", the word must be quoted
|
|
||||||
return keyword
|
|
||||||
}
|
|
||||||
val index2 = keyword.indexOf(' ')
|
|
||||||
return if (index2 <= index1) {
|
|
||||||
// Can't find space, or space is before :
|
|
||||||
keyword
|
|
||||||
} else keyword.substring(0, index1 + 1) + "\"" + keyword.substring(index1 + 1) + "$\""
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update search bar title, drawer checked item
|
// Update search bar title, drawer checked item
|
||||||
private fun onUpdateUrlBuilder() {
|
private fun onUpdateUrlBuilder() {
|
||||||
_binding ?: return
|
_binding ?: return
|
||||||
@@ -332,8 +323,8 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
|
|
||||||
// Update search edit text
|
// Update search edit text
|
||||||
if (!mIsTopList) {
|
if (!mIsTopList) {
|
||||||
if (mode == ListUrlBuilder.MODE_TAG) {
|
if (mode == MODE_TAG) {
|
||||||
keyword = wrapTagKeyword(keyword)
|
keyword = wrapTagKeyword(keyword!!)
|
||||||
}
|
}
|
||||||
setSearchBarText(keyword)
|
setSearchBarText(keyword)
|
||||||
}
|
}
|
||||||
@@ -547,7 +538,8 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
qsDrawerAdapter.setHasStableIds(true)
|
qsDrawerAdapter.setHasStableIds(true)
|
||||||
drawerBinding.recyclerViewDrawer.adapter = qsDrawerAdapter
|
drawerBinding.recyclerViewDrawer.adapter = qsDrawerAdapter
|
||||||
if (!mIsTopList) {
|
if (!mIsTopList) {
|
||||||
val itemTouchHelper = ItemTouchHelper(GalleryListQSItemTouchHelperCallback(qsDrawerAdapter))
|
val itemTouchHelper =
|
||||||
|
ItemTouchHelper(GalleryListQSItemTouchHelperCallback(qsDrawerAdapter))
|
||||||
itemTouchHelper.attachToRecyclerView(drawerBinding.recyclerViewDrawer)
|
itemTouchHelper.attachToRecyclerView(drawerBinding.recyclerViewDrawer)
|
||||||
drawerBinding.tip.visibility = View.VISIBLE
|
drawerBinding.tip.visibility = View.VISIBLE
|
||||||
drawerBinding.recyclerViewDrawer.visibility = View.GONE
|
drawerBinding.recyclerViewDrawer.visibility = View.GONE
|
||||||
@@ -995,7 +987,7 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
val oldMode = mUrlBuilder.mode
|
val oldMode = mUrlBuilder.mode
|
||||||
// If it's MODE_SUBSCRIPTION, keep it
|
// If it's MODE_SUBSCRIPTION, keep it
|
||||||
val newMode =
|
val newMode =
|
||||||
if (oldMode == MODE_SUBSCRIPTION) MODE_SUBSCRIPTION else ListUrlBuilder.MODE_NORMAL
|
if (oldMode == MODE_SUBSCRIPTION) MODE_SUBSCRIPTION else MODE_NORMAL
|
||||||
mUrlBuilder.reset()
|
mUrlBuilder.reset()
|
||||||
mUrlBuilder.mode = newMode
|
mUrlBuilder.mode = newMode
|
||||||
mUrlBuilder.keyword = query
|
mUrlBuilder.keyword = query
|
||||||
@@ -1155,8 +1147,7 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
val goto = if (i != -1) q.name!!.substring(i + 1) else null
|
val goto = if (i != -1) q.name!!.substring(i + 1) else null
|
||||||
val args = ListUrlBuilder().apply {
|
val args = ListUrlBuilder().apply {
|
||||||
set(q)
|
set(q)
|
||||||
setIndex(goto)
|
}.toStartArgs().apply { putString(KEY_GOTO, goto) }
|
||||||
}.toStartArgs()
|
|
||||||
navigate(R.id.galleryListScene, args, true)
|
navigate(R.id.galleryListScene, args, true)
|
||||||
setState(STATE_NORMAL)
|
setState(STATE_NORMAL)
|
||||||
closeDrawer(GravityCompat.END)
|
closeDrawer(GravityCompat.END)
|
||||||
@@ -1431,6 +1422,7 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY_ACTION = "action"
|
const val KEY_ACTION = "action"
|
||||||
|
const val KEY_GOTO = "goto"
|
||||||
const val ACTION_HOMEPAGE = "action_homepage"
|
const val ACTION_HOMEPAGE = "action_homepage"
|
||||||
const val ACTION_SUBSCRIPTION = "action_subscription"
|
const val ACTION_SUBSCRIPTION = "action_subscription"
|
||||||
const val ACTION_WHATS_HOT = "action_whats_hot"
|
const val ACTION_WHATS_HOT = "action_whats_hot"
|
||||||
@@ -1444,38 +1436,6 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
private const val STATE_SEARCH = 2
|
private const val STATE_SEARCH = 2
|
||||||
private const val STATE_SEARCH_SHOW_LIST = 3
|
private const val STATE_SEARCH_SHOW_LIST = 3
|
||||||
private const val ANIMATE_TIME = 300L
|
private const val ANIMATE_TIME = 300L
|
||||||
private fun getSuitableTitleForUrlBuilder(
|
|
||||||
resources: Resources, urlBuilder: ListUrlBuilder, appName: Boolean
|
|
||||||
): String? {
|
|
||||||
val keyword = urlBuilder.keyword
|
|
||||||
val category = urlBuilder.category
|
|
||||||
return if (ListUrlBuilder.MODE_NORMAL == urlBuilder.mode && EhUtils.NONE == category &&
|
|
||||||
TextUtils.isEmpty(keyword) && urlBuilder.advanceSearch == -1 && urlBuilder.minRating == -1 && urlBuilder.pageFrom == -1 && urlBuilder.pageTo == -1
|
|
||||||
) {
|
|
||||||
resources.getString(if (appName) R.string.app_name else R.string.homepage)
|
|
||||||
} else if (MODE_SUBSCRIPTION == urlBuilder.mode && EhUtils.NONE == category &&
|
|
||||||
TextUtils.isEmpty(keyword) && urlBuilder.advanceSearch == -1 && urlBuilder.minRating == -1 && urlBuilder.pageFrom == -1 && urlBuilder.pageTo == -1
|
|
||||||
) {
|
|
||||||
resources.getString(R.string.subscription)
|
|
||||||
} else if (MODE_WHATS_HOT == urlBuilder.mode) {
|
|
||||||
resources.getString(R.string.whats_hot)
|
|
||||||
} else if (MODE_TOPLIST == urlBuilder.mode) {
|
|
||||||
when (urlBuilder.keyword) {
|
|
||||||
"11" -> resources.getString(R.string.toplist_alltime)
|
|
||||||
"12" -> resources.getString(R.string.toplist_pastyear)
|
|
||||||
"13" -> resources.getString(R.string.toplist_pastmonth)
|
|
||||||
"15" -> resources.getString(R.string.toplist_yesterday)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
} else if (!TextUtils.isEmpty(keyword)) {
|
|
||||||
keyword
|
|
||||||
} else if (MathUtils.hammingWeight(category) == 1) {
|
|
||||||
EhUtils.getCategory(category)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ListUrlBuilder.toStartArgs(): Bundle {
|
fun ListUrlBuilder.toStartArgs(): Bundle {
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
args.putString(KEY_ACTION, ACTION_LIST_URL_BUILDER)
|
args.putString(KEY_ACTION, ACTION_LIST_URL_BUILDER)
|
||||||
@@ -1483,4 +1443,40 @@ class GalleryListScene : SearchBarScene(), OnDragHandlerListener, SearchLayout.H
|
|||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSuitableTitleForUrlBuilder(
|
||||||
|
resources: Resources, urlBuilder: ListUrlBuilder, appName: Boolean
|
||||||
|
): String? {
|
||||||
|
val keyword = urlBuilder.keyword
|
||||||
|
val category = urlBuilder.category
|
||||||
|
val mode = urlBuilder.mode
|
||||||
|
return if (mode == MODE_WHATS_HOT) {
|
||||||
|
resources.getString(R.string.whats_hot)
|
||||||
|
} else if (!keyword.isNullOrEmpty()) {
|
||||||
|
when (mode) {
|
||||||
|
MODE_TOPLIST -> {
|
||||||
|
when (keyword) {
|
||||||
|
"11" -> resources.getString(R.string.toplist_alltime)
|
||||||
|
"12" -> resources.getString(R.string.toplist_pastyear)
|
||||||
|
"13" -> resources.getString(R.string.toplist_pastmonth)
|
||||||
|
"15" -> resources.getString(R.string.toplist_yesterday)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MODE_TAG -> wrapTagKeyword(keyword)
|
||||||
|
else -> keyword
|
||||||
|
}
|
||||||
|
} else if (category == EhUtils.NONE && urlBuilder.advanceSearch == -1) {
|
||||||
|
when (mode) {
|
||||||
|
MODE_NORMAL -> resources.getString(if (appName) R.string.app_name else R.string.homepage)
|
||||||
|
MODE_SUBSCRIPTION -> resources.getString(R.string.subscription)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
} else if (category.countOneBits() == 1) {
|
||||||
|
EhUtils.getCategory(category)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -127,6 +127,7 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene {
|
|||||||
|
|
||||||
fun setSearchBarText(text: String?) {
|
fun setSearchBarText(text: String?) {
|
||||||
binding.toolbar.text = text
|
binding.toolbar.text = text
|
||||||
|
binding.searchview.setText(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setEditTextHint(hint: String?) {
|
fun setEditTextHint(hint: String?) {
|
||||||
@@ -168,18 +169,6 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene {
|
|||||||
mAllowEmptySearch = allowEmptySearch
|
mAllowEmptySearch = allowEmptySearch
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wrapTagKeyword(keyword: String): String {
|
|
||||||
return if (keyword.endsWith(':')) {
|
|
||||||
keyword
|
|
||||||
} else if (keyword.contains(' ')) {
|
|
||||||
val tag = keyword.substringAfter(':')
|
|
||||||
val prefix = keyword.dropLast(tag.length)
|
|
||||||
"$prefix\"$tag$\" "
|
|
||||||
} else {
|
|
||||||
"$keyword$ "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SuggestionProvider {
|
interface SuggestionProvider {
|
||||||
|
|
||||||
fun providerSuggestions(text: String): List<Suggestion>?
|
fun providerSuggestions(text: String): List<Suggestion>?
|
||||||
@@ -268,7 +257,7 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene {
|
|||||||
edittext.let {
|
edittext.let {
|
||||||
val keywords = it.text.toString().substringBeforeLast(' ', "")
|
val keywords = it.text.toString().substringBeforeLast(' ', "")
|
||||||
val keyword = wrapTagKeyword(mKeyword)
|
val keyword = wrapTagKeyword(mKeyword)
|
||||||
val newKeywords = if (keywords.isNotEmpty()) "$keywords $keyword" else keyword
|
val newKeywords = if (keywords.isNotEmpty()) "$keywords $keyword " else "$keyword "
|
||||||
it.setText(newKeywords)
|
it.setText(newKeywords)
|
||||||
it.setSelection(newKeywords.length)
|
it.setSelection(newKeywords.length)
|
||||||
}
|
}
|
||||||
@@ -370,3 +359,15 @@ abstract class SearchBarScene : BaseScene(), ToolBarScene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun wrapTagKeyword(keyword: String): String {
|
||||||
|
return if (keyword.endsWith(':')) {
|
||||||
|
keyword
|
||||||
|
} else if (keyword.contains(' ')) {
|
||||||
|
val tag = keyword.substringAfter(':')
|
||||||
|
val prefix = keyword.dropLast(tag.length)
|
||||||
|
"$prefix\"$tag$\""
|
||||||
|
} else {
|
||||||
|
"$keyword$"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -56,8 +56,8 @@ class Image private constructor(private val src: CloseableSource) {
|
|||||||
(mObtainedDrawable as? AnimatedImageDrawable)?.stop()
|
(mObtainedDrawable as? AnimatedImageDrawable)?.stop()
|
||||||
(mObtainedDrawable as? BitmapDrawable)?.bitmap?.recycle()
|
(mObtainedDrawable as? BitmapDrawable)?.bitmap?.recycle()
|
||||||
mObtainedDrawable?.callback = null
|
mObtainedDrawable?.callback = null
|
||||||
mObtainedDrawable = null
|
|
||||||
(mObtainedDrawable as? AnimatedImageDrawable)?.let { src.close() }
|
(mObtainedDrawable as? AnimatedImageDrawable)?.let { src.close() }
|
||||||
|
mObtainedDrawable = null
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
Reference in new issue
Block a user