Skip to content

Commit

Permalink
Merge pull request #663 from LoxiaLiSA/master
Browse files Browse the repository at this point in the history
fancy repo
  • Loading branch information
CeuiLiSA authored Dec 4, 2024
2 parents 59d7327 + 916cce7 commit c90f97d
Show file tree
Hide file tree
Showing 41 changed files with 808 additions and 375 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions annotations/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ plugins {
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
6 changes: 3 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ android {

compileOptions {
coreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}

sourceSets {
Expand All @@ -74,7 +74,7 @@ android {

namespace 'ceui.lisa'
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17
jvmTarget = JavaVersion.VERSION_21
}
}

Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/ceui/lisa/fragments/WebNovelParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ceui.lisa.utils.Common
import ceui.loxia.PixivHtmlObject
import ceui.loxia.SpaceHolder
import ceui.loxia.WebNovel
import ceui.loxia.novel.NovelChapterHolder
import ceui.loxia.novel.NovelImageHolder
import ceui.loxia.novel.NovelTextHolder
import ceui.pixiv.ui.common.ListItemHolder
Expand Down Expand Up @@ -121,10 +122,18 @@ abstract class WebNovelParser(response: Response<ResponseBody>) {
)
} else if (s.contains("[newpage]")) {
holderList.add(SpaceHolder())
} else if (s.contains("[chapter:")) {
holderList.add(NovelChapterHolder(extractChapterContent(s) ?: "", Common.getNovelTextColor()))
} else {
holderList.add(NovelTextHolder(s, Common.getNovelTextColor()))
}
return holderList
}

private fun extractChapterContent(input: String): String? {
val regex = """\[chapter:(.+?)]""".toRegex()
val matchResult = regex.find(input)
return matchResult?.groups?.get(1)?.value
}
}
}
6 changes: 6 additions & 0 deletions app/src/main/java/ceui/loxia/SquareResponse.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ data class Page(
val follow: List<Long>? = null,
val recommend: IdsHolder? = null,
val ranking: RankingHolder? = null,
val editorRecommend: List<EditorRecommend>? = null,
) : Serializable

data class EditorRecommend(
val illustId: Long? = null,
val comment: String? = null,
) : Serializable

data class IdsHolder(
Expand Down
106 changes: 100 additions & 6 deletions app/src/main/java/ceui/loxia/UIAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,36 @@ package ceui.loxia

import android.os.Bundle
import android.view.View
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.findFragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.navigation.NavOptions
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.RecyclerView
import ceui.lisa.R
import ceui.lisa.utils.Common
import ceui.pixiv.ui.common.FragmentResultRequestIdOwner
import ceui.pixiv.widgets.FragmentResultByFragment
import ceui.pixiv.widgets.FragmentResultStore
import ceui.pixiv.widgets.PixivDialog
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlin.reflect.KClass
import java.util.UUID

inline fun<reified InterfaceT> Fragment.sendAction(action: (receiver: InterfaceT)->Boolean) {
inline fun <reified InterfaceT> Fragment.sendAction(action: (receiver: InterfaceT) -> Boolean) {
var received = false
var itr: Fragment? = this
while (itr != null) {
val receiver = itr as? InterfaceT
if (receiver != null && action(receiver)) {
if (receiver != null && action(receiver)) {
received = true
break
} else {
Expand All @@ -34,7 +47,7 @@ inline fun<reified InterfaceT> Fragment.sendAction(action: (receiver: InterfaceT
}
}

inline fun<reified InterfaceT> View.sendAction(action: (receiver: InterfaceT)->Boolean) {
inline fun <reified InterfaceT> View.sendAction(action: (receiver: InterfaceT) -> Boolean) {
val fragment = this.findFragment<Fragment>()
fragment.sendAction<InterfaceT>(action)
}
Expand Down Expand Up @@ -97,6 +110,87 @@ fun NavOptions.Builder.setFadeIn(): NavOptions.Builder {
.setPopExitAnim(R.anim.slow_fade_out)
}

const val FRAGMENT_RESULT_REQUEST_ID = "FragmentResultRequestId"


internal fun<T> T.listenToResultStore(resultStore: FragmentResultStore) where T: Fragment, T: FragmentResultRequestIdOwner {
val fragment = this
val uniqueId = fragmentUniqueId
viewLifecycleOwner.lifecycleScope.launchWhenResumed {
resultStore.getTypedResult(uniqueId)?.let { result ->
resultStore.getTypedTask(uniqueId)?.let { task ->
task.complete(FragmentResultByFragment(result, fragment))
resultStore.removeResult(uniqueId)
}
}
}
}

inline fun <FragmentT, reified T> FragmentT.pushFragmentForResult(
id: Int,
bundle: Bundle? = null,
crossinline onResult: FragmentT.(T) -> Unit
) where FragmentT : Fragment, FragmentT : FragmentResultRequestIdOwner {
val caller = this
Common.showLog("dsaasdw gogogogo ${caller.fragmentUniqueId} picked launchWhenResumed use ${lifecycle.currentState}")

val fragmentResultStore by activityViewModels<FragmentResultStore>()
val requestId = fragmentUniqueId
val task = CompletableDeferred<FragmentResultByFragment<FragmentT, T>>()
fragmentResultStore.putTask(requestId, task as CompletableDeferred<FragmentResultByFragment<*, *>>)

// 如果 bundle 为 null,则创建一个新的 Bundle
val args = bundle ?: Bundle()
// 将 requestId 添加到 Bundle 中
args.putString(FRAGMENT_RESULT_REQUEST_ID, requestId)

MainScope().launch {
val result = task.await()
result.fragment.onResult(result.result)
}
findNavController().navigate(
id,
args,
NavOptions.Builder().setHorizontalSlide().build()
)
}


inline fun <FragmentT, reified T> FragmentT.promptFragmentForResult(
dialogProducer: () -> DialogFragment,
bundle: Bundle? = null,
crossinline onResult: FragmentT.(T) -> Unit
) where FragmentT : Fragment, FragmentT : FragmentResultRequestIdOwner {
val caller = this
Common.showLog("dsaasdw gogogogo ${caller.fragmentUniqueId} picked launchWhenResumed use ${lifecycle.currentState}")

val fragmentResultStore by activityViewModels<FragmentResultStore>()
val requestId = fragmentUniqueId
val task = CompletableDeferred<FragmentResultByFragment<FragmentT, T>>()
fragmentResultStore.putTask(requestId, task as CompletableDeferred<FragmentResultByFragment<*, *>>)
fragmentResultStore.registerListener(requestId, lifecycle)
lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
fragmentResultStore.unRegisterListener(requestId)
}
})

// 如果 bundle 为 null,则创建一个新的 Bundle
val args = bundle ?: Bundle()
// 将 requestId 添加到 Bundle 中
args.putString(FRAGMENT_RESULT_REQUEST_ID, requestId)

MainScope().launch {
val result = task.await()
result.fragment.onResult(result.result)
}
val dialogFragment = dialogProducer()
dialogFragment.apply {
arguments = args
}
dialogFragment.show(childFragmentManager, "Tag")
}

fun Fragment.pushFragment(id: Int, bundle: Bundle? = null) {
findNavController().navigate(
Expand Down Expand Up @@ -129,12 +223,12 @@ inline fun <reified ActionReceiverT> Fragment.findActionReceiverOrNull(): Action
}


inline fun<reified ActionReceiverT> View.findActionReceiverOrNull(): ActionReceiverT? {
inline fun <reified ActionReceiverT> View.findActionReceiverOrNull(): ActionReceiverT? {
val fragment = this.findFragmentOrNull<Fragment>()
return fragment?.findActionReceiverOrNull<ActionReceiverT>()
}

inline fun<reified ActionReceiverT> View.findActionReceiver(): ActionReceiverT {
inline fun <reified ActionReceiverT> View.findActionReceiver(): ActionReceiverT {
val fragment = this.findFragment<Fragment>()
return fragment.findActionReceiverOrNull<ActionReceiverT>()!!
}
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/ceui/loxia/novel/NovelTextHolder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.core.content.ContextCompat
import ceui.lisa.R
import ceui.lisa.activities.Shaft
import ceui.lisa.annotations.ItemHolder
import ceui.lisa.databinding.CellNovelChapterBinding
import ceui.lisa.databinding.CellNovelImageBinding
import ceui.lisa.databinding.CellNovelTextBinding
import ceui.lisa.utils.GlideUrlChild
Expand All @@ -17,6 +18,23 @@ import com.bumptech.glide.Glide
import com.bumptech.glide.load.model.GlideUrl
import java.util.HashMap

class NovelChapterHolder(val text: String, val textColor: Int) : ListItemHolder() {
override fun getItemId(): Long {
return (text.hashCode() + textColor).toLong()
}
}

@ItemHolder(NovelChapterHolder::class)
class NovelChapterViewHolder(bd: CellNovelChapterBinding) : ListItemViewHolder<CellNovelChapterBinding, NovelChapterHolder>(bd) {

override fun onBindViewHolder(holder: NovelChapterHolder, position: Int) {
super.onBindViewHolder(holder, position)
binding.novelText.text = holder.text
binding.novelText.setTextColor(holder.textColor)
}
}


class NovelTextHolder(val text: String, val textColor: Int) : ListItemHolder() {
override fun getItemId(): Long {
return (text.hashCode() + textColor).toLong()
Expand Down
16 changes: 2 additions & 14 deletions app/src/main/java/ceui/pixiv/ui/bottom/ItemListDialogFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsCompat.Type.systemBars
import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.marginTop
import androidx.fragment.app.setFragmentResult
import androidx.lifecycle.LiveData
import ceui.lisa.R
import ceui.lisa.annotations.ItemHolder
Expand Down Expand Up @@ -70,21 +71,8 @@ class ItemListDialogFragment : PixivBottomSheet(R.layout.fragment_item_list_dial
}
}

companion object {

// TODO: Customize parameters
fun newInstance(itemCount: Int): ItemListDialogFragment =
ItemListDialogFragment().apply {
arguments = Bundle().apply {
putInt(ARG_ITEM_COUNT, itemCount)
}
}

}

override fun onClickOffsetPage(index: Int) {
viewModel.choosenOffsetPage.value = index
viewModel.triggerOffsetPageEvent.value = Event(index)
setFragmentResult(index)
dismissAllowingStateLoss()
}
}
Expand Down
16 changes: 4 additions & 12 deletions app/src/main/java/ceui/pixiv/ui/chats/MyChatsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,27 @@ class MyChatsFragment : TitledViewPagerFragment(R.layout.fragment_my_chats), Hom
arguments = SquareFragmentArgs(ObjectType.ILLUST).toBundle()
}
},
titleLiveData = getTitleLiveData(0).apply {
value = "插画"
}
initialTitle = "插画"
),
PagedFragmentItem(
builder = {
SquareFragment().apply {
arguments = SquareFragmentArgs(ObjectType.MANGA).toBundle()
}
},
titleLiveData = getTitleLiveData(1).apply {
value = "漫画"
}
initialTitle = "漫画"
),
PagedFragmentItem(
builder = {
ArticlesFragment()
},
titleLiveData = getTitleLiveData(2).apply {
value = "Pixivision"
}
initialTitle = "Pixivision"
),
PagedFragmentItem(
builder = {
WalkthroughFragment()
},
titleLiveData = getTitleLiveData(3).apply {
value = "画廊"
}
initialTitle = "画廊"
),
),
this
Expand Down
30 changes: 24 additions & 6 deletions app/src/main/java/ceui/pixiv/ui/chats/SquareFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,46 @@ class SquareFragment : PixivFragment(R.layout.fragment_pixiv_list) {
}
viewModel.result.observe(viewLifecycleOwner) { data ->
val holders = mutableListOf<ListItemHolder>()
data.body?.page?.recommend?.ids?.let { recommendIllustIds ->

data.body?.page?.ranking?.let { ranking ->
val webIllusts = mutableListOf<WebIllust>()
recommendIllustIds.forEach { id ->
ranking.items?.map { it.id }?.forEach { id ->
data.body.thumbnails?.illust?.firstOrNull { it.id == id }?.let { webIllust ->
webIllusts.add(webIllust)
}
}
holders.add(RedSectionHeaderHolder("Recommend Works"))
holders.add(RedSectionHeaderHolder("Ranking for ${ranking.date}"))
holders.addAll(webIllusts.map { IllustSquareHolder(it) })
}

data.body?.page?.ranking?.let { ranking ->

data.body?.page?.editorRecommend?.let { editorRecommend ->
val webIllusts = mutableListOf<WebIllust>()
ranking.items?.map { it.id }?.forEach { id ->
editorRecommend.forEach { recmd ->
recmd.illustId?.let { id ->
data.body.thumbnails?.illust?.firstOrNull { it.id == id }?.let { webIllust ->
webIllusts.add(webIllust)
}
}
}
holders.add(RedSectionHeaderHolder("Editor Recommend Works"))
holders.addAll(webIllusts.map { IllustSquareHolder(it) })
}


data.body?.page?.recommend?.ids?.let { recommendIllustIds ->
val webIllusts = mutableListOf<WebIllust>()
recommendIllustIds.forEach { id ->
data.body.thumbnails?.illust?.firstOrNull { it.id == id }?.let { webIllust ->
webIllusts.add(webIllust)
}
}
holders.add(RedSectionHeaderHolder("Ranking for ${ranking.date}"))
holders.add(RedSectionHeaderHolder("Recommend Works"))
holders.addAll(webIllusts.map { IllustSquareHolder(it) })
}



data.body?.page?.recommendByTag?.forEach { tag ->
val webIllusts = mutableListOf<WebIllust>()
tag.ids?.forEach { id ->
Expand Down
Loading

0 comments on commit c90f97d

Please sign in to comment.