Fixed a few things...
Can't really write them all down :v
This commit is contained in:
2
.idea/deploymentTargetDropDown.xml
generated
2
.idea/deploymentTargetDropDown.xml
generated
@@ -12,6 +12,6 @@
|
|||||||
</deviceKey>
|
</deviceKey>
|
||||||
</Target>
|
</Target>
|
||||||
</targetSelectedWithDropDown>
|
</targetSelectedWithDropDown>
|
||||||
<timeTargetWasSelectedWithDropDown value="2021-12-21T10:21:31.281798Z" />
|
<timeTargetWasSelectedWithDropDown value="2021-12-25T06:38:27.847239Z" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -74,7 +74,6 @@ class Pupil : Application(), DIAware {
|
|||||||
socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS
|
socketTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS
|
||||||
connectTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS
|
connectTimeoutMillis = HttpTimeout.INFINITE_TIMEOUT_MS
|
||||||
}
|
}
|
||||||
install(HttpCache)
|
|
||||||
|
|
||||||
BrowserUserAgent()
|
BrowserUserAgent()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ fun FloatingSearchBar(
|
|||||||
onQueryChange: (String) -> Unit = { },
|
onQueryChange: (String) -> Unit = { },
|
||||||
navigationIcon: @Composable () -> Unit = { },
|
navigationIcon: @Composable () -> Unit = { },
|
||||||
actions: @Composable RowScope.() -> Unit = { },
|
actions: @Composable RowScope.() -> Unit = { },
|
||||||
|
onSearch: () -> Unit = { },
|
||||||
onTextFieldFocused: () -> Unit = { },
|
onTextFieldFocused: () -> Unit = { },
|
||||||
onTextFieldUnfocused: () -> Unit = { }
|
onTextFieldUnfocused: () -> Unit = { }
|
||||||
) {
|
) {
|
||||||
@@ -100,9 +101,7 @@ fun FloatingSearchBar(
|
|||||||
cursorBrush = SolidColor(MaterialTheme.colors.secondary),
|
cursorBrush = SolidColor(MaterialTheme.colors.secondary),
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||||
keyboardActions = KeyboardActions(
|
keyboardActions = KeyboardActions(
|
||||||
onSearch = {
|
onSearch = { onSearch() }
|
||||||
focusManager.clearFocus()
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
decorationBox = { innerTextField ->
|
decorationBox = { innerTextField ->
|
||||||
Row(
|
Row(
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Pupil, Hitomi.la viewer for Android
|
|
||||||
* Copyright (C) 2021 tom5079
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package xyz.quaver.pupil.sources.composable
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun <T> ListSearchResult(searchResults: List<T>, contentPadding: PaddingValues = PaddingValues(0.dp), content: @Composable (T) -> Unit) {
|
|
||||||
LazyColumn(
|
|
||||||
Modifier.fillMaxSize(),
|
|
||||||
contentPadding = contentPadding,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
|
||||||
) {
|
|
||||||
items(searchResults) { itemInfo ->
|
|
||||||
content(itemInfo)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
package xyz.quaver.pupil.sources.composable
|
package xyz.quaver.pupil.sources.composable
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||||
@@ -41,17 +40,19 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
|||||||
import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
|
import androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed
|
||||||
import androidx.compose.ui.input.pointer.consumePositionChange
|
import androidx.compose.ui.input.pointer.consumePositionChange
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.util.fastFirstOrNull
|
import androidx.compose.ui.util.fastFirstOrNull
|
||||||
import com.google.accompanist.insets.LocalWindowInsets
|
|
||||||
import com.google.accompanist.insets.rememberInsetsPaddingValues
|
|
||||||
import xyz.quaver.pupil.R
|
import xyz.quaver.pupil.R
|
||||||
import xyz.quaver.pupil.ui.theme.LightBlue300
|
import xyz.quaver.pupil.ui.theme.LightBlue300
|
||||||
import kotlin.math.*
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
import kotlin.math.sign
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun OverscrollPager(
|
fun OverscrollPager(
|
||||||
@@ -68,8 +69,10 @@ fun OverscrollPager(
|
|||||||
|
|
||||||
var overscroll: Float? by remember { mutableStateOf(null) }
|
var overscroll: Float? by remember { mutableStateOf(null) }
|
||||||
|
|
||||||
val topCircleRadius by animateFloatAsState(if (overscroll?.let { it >= pageTurnIndicatorHeight } == true) 1000f else 0f)
|
val screenWidth = LocalConfiguration.current.screenWidthDp
|
||||||
val bottomCircleRadius by animateFloatAsState(if (overscroll?.let { it <= -pageTurnIndicatorHeight } == true) 1000f else 0f)
|
|
||||||
|
val topCircleRadius by animateFloatAsState(if (overscroll?.let { it >= pageTurnIndicatorHeight } == true) screenWidth.toFloat() else 0f)
|
||||||
|
val bottomCircleRadius by animateFloatAsState(if (overscroll?.let { it <= -pageTurnIndicatorHeight } == true) screenWidth.toFloat() else 0f)
|
||||||
|
|
||||||
val prevPageTurnIndicatorOffsetPx = LocalDensity.current.run { prevPageTurnIndicatorOffset.toPx() }
|
val prevPageTurnIndicatorOffsetPx = LocalDensity.current.run { prevPageTurnIndicatorOffset.toPx() }
|
||||||
val nextPageTurnIndicatorOffsetPx = LocalDensity.current.run { nextPageTurnIndicatorOffset.toPx() }
|
val nextPageTurnIndicatorOffsetPx = LocalDensity.current.run { nextPageTurnIndicatorOffset.toPx() }
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ open class SearchBaseViewModel<T>(app: Application) : AndroidViewModel(app) {
|
|||||||
var query by mutableStateOf("")
|
var query by mutableStateOf("")
|
||||||
|
|
||||||
var loading by mutableStateOf(false)
|
var loading by mutableStateOf(false)
|
||||||
|
var error by mutableStateOf(false)
|
||||||
|
|
||||||
//region UI
|
//region UI
|
||||||
var isFabVisible by mutableStateOf(true)
|
var isFabVisible by mutableStateOf(true)
|
||||||
@@ -139,7 +140,7 @@ fun <T> SearchBase(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
Box(Modifier.padding(contentPadding)) {
|
Box(Modifier.padding(contentPadding).fillMaxSize()) {
|
||||||
OverscrollPager(
|
OverscrollPager(
|
||||||
currentPage = model.currentPage,
|
currentPage = model.currentPage,
|
||||||
prevPageAvailable = model.prevPageAvailable,
|
prevPageAvailable = model.prevPageAvailable,
|
||||||
@@ -191,8 +192,9 @@ fun <T> SearchBase(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = actions,
|
actions = actions,
|
||||||
|
onSearch = { onSearch(); focusManager.clearFocus() },
|
||||||
onTextFieldFocused = { navigationIconState = NavigationIconState.ARROW },
|
onTextFieldFocused = { navigationIconState = NavigationIconState.ARROW },
|
||||||
onTextFieldUnfocused = { navigationIconState = NavigationIconState.MENU; onSearch() }
|
onTextFieldUnfocused = { navigationIconState = NavigationIconState.MENU }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ import androidx.compose.foundation.layout.Arrangement
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.foundation.lazy.GridCells
|
||||||
|
import androidx.compose.foundation.lazy.LazyVerticalGrid
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.*
|
import androidx.compose.material.icons.filled.*
|
||||||
@@ -187,21 +190,26 @@ class Hitomi(app: Application) : Source(), DIAware {
|
|||||||
},
|
},
|
||||||
onSearch = { model.search() }
|
onSearch = { model.search() }
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
ListSearchResult(model.searchResults, contentPadding = contentPadding) {
|
LazyVerticalGrid(
|
||||||
DetailedSearchResult(
|
cells = GridCells.Adaptive(minSize = 500.dp),
|
||||||
it,
|
contentPadding = contentPadding
|
||||||
bookmarks = bookmarkSet,
|
) {
|
||||||
onBookmarkToggle = {
|
items(model.searchResults) {
|
||||||
coroutineScope.launch {
|
DetailedSearchResult(
|
||||||
if (it in bookmarkSet) bookmarkDao.delete(name, it)
|
it,
|
||||||
else bookmarkDao.insert(name, it)
|
bookmarks = bookmarkSet,
|
||||||
|
onBookmarkToggle = {
|
||||||
|
coroutineScope.launch {
|
||||||
|
if (it in bookmarkSet) bookmarkDao.delete(name, it)
|
||||||
|
else bookmarkDao.insert(name, it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
) { result ->
|
||||||
|
logger.info {
|
||||||
|
result.toString()
|
||||||
|
}
|
||||||
|
navController.navigate("hitomi.la/reader/${result.itemID}")
|
||||||
}
|
}
|
||||||
) { result ->
|
|
||||||
logger.info {
|
|
||||||
result.toString()
|
|
||||||
}
|
|
||||||
navController.navigate("hitomi.la/reader/${result.itemID}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package xyz.quaver.pupil.sources.hitomi
|
package xyz.quaver.pupil.sources.hitomi
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.util.LruCache
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
@@ -39,6 +40,8 @@ import xyz.quaver.pupil.sources.hitomi.lib.GalleryBlock
|
|||||||
import xyz.quaver.pupil.sources.hitomi.lib.doSearch
|
import xyz.quaver.pupil.sources.hitomi.lib.doSearch
|
||||||
import xyz.quaver.pupil.sources.hitomi.lib.getGalleryBlock
|
import xyz.quaver.pupil.sources.hitomi.lib.getGalleryBlock
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel<HitomiSearchResult>(app), DIAware {
|
class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel<HitomiSearchResult>(app), DIAware {
|
||||||
override val di by closestDI(app)
|
override val di by closestDI(app)
|
||||||
@@ -54,6 +57,8 @@ class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel<Hitomi
|
|||||||
private var cachedSortByPopularity: Boolean? = null
|
private var cachedSortByPopularity: Boolean? = null
|
||||||
private val cache = mutableListOf<Int>()
|
private val cache = mutableListOf<Int>()
|
||||||
|
|
||||||
|
private val galleryBlockCache = LruCache<Int, GalleryBlock>(100)
|
||||||
|
|
||||||
var sortByPopularity by mutableStateOf(false)
|
var sortByPopularity by mutableStateOf(false)
|
||||||
|
|
||||||
private var searchJob: Job? = null
|
private var searchJob: Job? = null
|
||||||
@@ -66,6 +71,7 @@ class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel<Hitomi
|
|||||||
searchResults.clear()
|
searchResults.clear()
|
||||||
searchBarOffset = 0
|
searchBarOffset = 0
|
||||||
loading = true
|
loading = true
|
||||||
|
error = false
|
||||||
|
|
||||||
searchJob = launch {
|
searchJob = launch {
|
||||||
if (cachedQuery != query || cachedSortByPopularity != sortByPopularity || cache.isEmpty()) {
|
if (cachedQuery != query || cachedSortByPopularity != sortByPopularity || cache.isEmpty()) {
|
||||||
@@ -74,21 +80,41 @@ class HitomiSearchResultViewModel(app: Application) : SearchBaseViewModel<Hitomi
|
|||||||
|
|
||||||
yield()
|
yield()
|
||||||
|
|
||||||
val result = doSearch(client, query, sortByPopularity)
|
val result = runCatching {
|
||||||
|
doSearch(client, query, sortByPopularity)
|
||||||
|
}.onFailure {
|
||||||
|
error = true
|
||||||
|
}.getOrNull()
|
||||||
|
|
||||||
yield()
|
yield()
|
||||||
|
|
||||||
cache.addAll(result)
|
result?.let { cache.addAll(result) }
|
||||||
cachedQuery = query
|
cachedQuery = query
|
||||||
totalItems = result.size
|
totalItems = result?.size ?: 0
|
||||||
maxPage = ceil(result.size / resultsPerPage.toDouble()).toInt()
|
maxPage =
|
||||||
|
result?.let { ceil(result.size / resultsPerPage.toDouble()).toInt() }
|
||||||
|
?: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.slice((currentPage-1)*resultsPerPage until currentPage*resultsPerPage).forEach { galleryID ->
|
yield()
|
||||||
yield()
|
|
||||||
loading = false
|
val range = max((currentPage-1)*resultsPerPage, 0) until min(currentPage*resultsPerPage, totalItems)
|
||||||
searchResults.add(transform(getGalleryBlock(client, galleryID)))
|
|
||||||
}
|
cache.slice(range)
|
||||||
|
.forEach { galleryID ->
|
||||||
|
yield()
|
||||||
|
loading = false
|
||||||
|
kotlin.runCatching {
|
||||||
|
galleryBlockCache.get(galleryID) ?: getGalleryBlock(client, galleryID).also {
|
||||||
|
galleryBlockCache.put(galleryID, it)
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
error = true
|
||||||
|
}.getOrNull()?.let {
|
||||||
|
searchResults.add(transform(it))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
package xyz.quaver.pupil.sources.hitomi.composable
|
package xyz.quaver.pupil.sources.hitomi.composable
|
||||||
|
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
@@ -107,7 +108,7 @@ fun DetailedSearchResult(
|
|||||||
|
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(8.dp, 0.dp)
|
.padding(8.dp)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.clickable { onClick(result) },
|
.clickable { onClick(result) },
|
||||||
elevation = 4.dp
|
elevation = 4.dp
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ suspend fun fetchNozomi(
|
|||||||
val startByte = start*4
|
val startByte = start*4
|
||||||
val endByte = (start+count)*4-1
|
val endByte = (start+count)*4-1
|
||||||
|
|
||||||
append("Range", "bytes=$startByte-$endByte")
|
set("Range", "bytes=$startByte-$endByte")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,12 @@
|
|||||||
|
|
||||||
package xyz.quaver.pupil.sources.hitomi.lib
|
package xyz.quaver.pupil.sources.hitomi.lib
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import io.ktor.client.*
|
import io.ktor.client.*
|
||||||
|
import io.ktor.client.call.*
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
|
import io.ktor.client.statement.*
|
||||||
|
import io.ktor.util.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
@@ -36,8 +40,15 @@ const val max_node_size = 464
|
|||||||
const val B = 16
|
const val B = 16
|
||||||
const val compressed_nozomi_prefix = "n"
|
const val compressed_nozomi_prefix = "n"
|
||||||
|
|
||||||
var tag_index_version: String? = null
|
var _tag_index_version: String? = null
|
||||||
var galleries_index_version: String? = null
|
suspend fun getTagIndexVersion(client: HttpClient): String = _tag_index_version ?: getIndexVersion(client, "tagindex").also {
|
||||||
|
_tag_index_version = it
|
||||||
|
}
|
||||||
|
|
||||||
|
var _galleries_index_version: String? = null
|
||||||
|
suspend fun getGalleriesIndexVersion(client: HttpClient): String = _galleries_index_version ?: getIndexVersion(client, "galleriesindex").also {
|
||||||
|
_galleries_index_version = it
|
||||||
|
}
|
||||||
|
|
||||||
fun sha256(data: ByteArray) : ByteArray {
|
fun sha256(data: ByteArray) : ByteArray {
|
||||||
return MessageDigest.getInstance("SHA-256").digest(data)
|
return MessageDigest.getInstance("SHA-256").digest(data)
|
||||||
@@ -118,7 +129,7 @@ suspend fun getSuggestionsForQuery(client: HttpClient, query: String) : List<Sug
|
|||||||
|
|
||||||
data class Suggestion(val s: String, val t: Int, val u: String, val n: String)
|
data class Suggestion(val s: String, val t: Int, val u: String, val n: String)
|
||||||
suspend fun getSuggestionsFromData(client: HttpClient, field: String, data: Pair<Long, Int>) : List<Suggestion> {
|
suspend fun getSuggestionsFromData(client: HttpClient, field: String, data: Pair<Long, Int>) : List<Suggestion> {
|
||||||
val url = "$protocol//$domain/$index_dir/$field.$tag_index_version.data"
|
val url = "$protocol//$domain/$index_dir/$field.${getTagIndexVersion(client)}.data"
|
||||||
val (offset, length) = data
|
val (offset, length) = data
|
||||||
if (length > 10000 || length <= 0)
|
if (length > 10000 || length <= 0)
|
||||||
throw Exception("length $length is too long")
|
throw Exception("length $length is too long")
|
||||||
@@ -188,7 +199,7 @@ suspend fun getGalleryIDsFromNozomi(client: HttpClient, area: String?, tag: Stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getGalleryIDsFromData(client: HttpClient, data: Pair<Long, Int>) : Set<Int> {
|
suspend fun getGalleryIDsFromData(client: HttpClient, data: Pair<Long, Int>) : Set<Int> {
|
||||||
val url = "$protocol//$domain/$galleries_index_dir/galleries.$galleries_index_version.data"
|
val url = "$protocol//$domain/$galleries_index_dir/galleries.${getGalleriesIndexVersion(client)}.data"
|
||||||
val (offset, length) = data
|
val (offset, length) = data
|
||||||
if (length > 100000000 || length <= 0)
|
if (length > 100000000 || length <= 0)
|
||||||
throw Exception("length $length is too long")
|
throw Exception("length $length is too long")
|
||||||
@@ -219,10 +230,10 @@ suspend fun getGalleryIDsFromData(client: HttpClient, data: Pair<Long, Int>) : S
|
|||||||
suspend fun getNodeAtAddress(client: HttpClient, field: String, address: Long) : Node? {
|
suspend fun getNodeAtAddress(client: HttpClient, field: String, address: Long) : Node? {
|
||||||
val url =
|
val url =
|
||||||
when(field) {
|
when(field) {
|
||||||
"galleries" -> "$protocol//$domain/$galleries_index_dir/galleries.$galleries_index_version.index"
|
"galleries" -> "$protocol//$domain/$galleries_index_dir/galleries.${getGalleriesIndexVersion(client)}.index"
|
||||||
"languages" -> "$protocol//$domain/$galleries_index_dir/languages.$galleries_index_version.index"
|
"languages" -> "$protocol//$domain/$galleries_index_dir/languages.${getGalleriesIndexVersion(client)}.index"
|
||||||
"nozomiurl" -> "$protocol//$domain/$galleries_index_dir/nozomiurl.$galleries_index_version.index"
|
"nozomiurl" -> "$protocol//$domain/$galleries_index_dir/nozomiurl.${getGalleriesIndexVersion(client)}.index"
|
||||||
else -> "$protocol//$domain/$index_dir/$field.$tag_index_version.index"
|
else -> "$protocol//$domain/$index_dir/$field.${getTagIndexVersion(client)}.index"
|
||||||
}
|
}
|
||||||
|
|
||||||
val nodedata = getURLAtRange(client, url, address.until(address+max_node_size))
|
val nodedata = getURLAtRange(client, url, address.until(address+max_node_size))
|
||||||
@@ -233,7 +244,7 @@ suspend fun getNodeAtAddress(client: HttpClient, field: String, address: Long) :
|
|||||||
suspend fun getURLAtRange(client: HttpClient, url: String, range: LongRange) : ByteArray = withContext(Dispatchers.IO) {
|
suspend fun getURLAtRange(client: HttpClient, url: String, range: LongRange) : ByteArray = withContext(Dispatchers.IO) {
|
||||||
client.get(url) {
|
client.get(url) {
|
||||||
headers {
|
headers {
|
||||||
append("Range", "bytes=${range.first}-${range.last}")
|
set("Range", "bytes=${range.first}-${range.last}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user