From 228e83038bbd4f8ff4c92dd453845364f8b3c051 Mon Sep 17 00:00:00 2001 From: ekibun Date: Thu, 21 Feb 2019 21:57:49 +0800 Subject: [PATCH] tinygrail --- app/src/main/AndroidManifest.xml | 4 + .../ekibun/bangumi/api/bangumi/Bangumi.kt | 115 +---------------- .../bangumi/api/bangumi/bean/SubjectType.kt | 3 +- .../ekibun/bangumi/api/tinygrail/Tinygrail.kt | 14 +++ .../bangumi/api/tinygrail/bean/OnAirInfo.kt | 14 +++ .../fragment/collection/SubjectTypeView.kt | 6 +- .../fragment/timeline/TimeLineFragment.kt | 6 +- .../main/fragment/index/IndexPagerAdapter.kt | 7 +- .../ui/main/fragment/index/IndexTypeView.kt | 76 +++++++++++ .../bangumi/ui/search/SearchTypeView.kt | 11 +- .../bangumi/ui/subject/SubjectActivity.kt | 2 +- .../bangumi/ui/subject/SubjectPresenter.kt | 22 ++++ .../ekibun/bangumi/ui/subject/SubjectView.kt | 23 +++- .../soko/ekibun/bangumi/ui/web/WebActivity.kt | 17 ++- app/src/main/res/layout/dialog_epsode.xml | 9 +- app/src/main/res/layout/dialog_infobox.xml | 10 ++ app/src/main/res/layout/item_subject.xml | 2 +- app/src/main/res/menu/list_browser_type.xml | 118 ++++++++++++++++++ 18 files changed, 320 insertions(+), 139 deletions(-) create mode 100644 app/src/main/java/soko/ekibun/bangumi/api/tinygrail/bean/OnAirInfo.kt create mode 100644 app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexTypeView.kt create mode 100644 app/src/main/res/layout/dialog_infobox.xml create mode 100644 app/src/main/res/menu/list_browser_type.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ab7ced6..644713b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -92,7 +92,11 @@ + diff --git a/app/src/main/java/soko/ekibun/bangumi/api/bangumi/Bangumi.kt b/app/src/main/java/soko/ekibun/bangumi/api/bangumi/Bangumi.kt index c7178a5..d47a707 100644 --- a/app/src/main/java/soko/ekibun/bangumi/api/bangumi/Bangumi.kt +++ b/app/src/main/java/soko/ekibun/bangumi/api/bangumi/Bangumi.kt @@ -1,7 +1,6 @@ package soko.ekibun.bangumi.api.bangumi import android.annotation.SuppressLint -import android.util.Log import android.webkit.CookieManager import okhttp3.FormBody import org.jsoup.Jsoup @@ -24,119 +23,14 @@ import kotlin.math.min interface Bangumi { - @GET("/search/subject/{keywords}") - fun search(@Path("keywords") keywords: String, - @SubjectType.SubjectType @Query("type") type: Int = SubjectType.ALL, - @Query("start")start: Int = 0, - @Query("max_results")max_results: Int = 10, - @Header("cookie") cookie: String = "chii_searchDateLine=0" - ): Call - - @GET("/subject/{id}") - fun subject(@Path("id") id: Int, - @ResponseGroup.ResponseGroup @Query("responseGroup") responseGroup: String = ResponseGroup.LARGE - ): Call - - @GET("/subject/{id}/ep") - fun subjectEp(@Path("id") id: Int): Call - - @GET("/user/{username}") - fun user(@Path("username") id: String - ): Call - @GET("/user/{username}/collection") fun collection(@Path("username") username: String, @Query("cat") cat: String = "all_watching" ): Call> - @GET("/collection/{subject_id}") - fun collectionStatus(@Path("subject_id") subject_id: Int, - @Query("access_token") access_token: String - ): Call - - @GET("/ep/{id}/status/{status}") - fun updateProgress(@Path("id") id: Int, - @SubjectProgress.EpisodeProgress.EpisodeStatus.Companion.EpStatusType - @Path("status") status: String, - @Query("access_token") access_token: String - ): Call - - @FormUrlEncoded - @POST("/subject/{subject_id}/update/watched_eps") - fun updateWatchEps(@Path("subject_id") subject_id: Int, - @Field("watched_eps") watched_eps: String, - @Query("access_token") access_token: String - ): Call - - @FormUrlEncoded - @POST("/ep/{id}/status/{status}") - fun updateProgress(@Path("id") id: Int, - @SubjectProgress.EpisodeProgress.EpisodeStatus.Companion.EpStatusType - @Path("status") status: String, - @Query("access_token") access_token: String, - @Field("ep_id") epIds: String - ): Call - - @GET("/user/{username}/progress") - fun progress(@Path("username") username: String, - @Query("subject_id") subject_id: Int, - @Query("access_token") access_token: String - ): Call - - @FormUrlEncoded - @POST("/collection/{subject_id}/update") - fun updateCollectionStatus(@Path("subject_id") subject_id: Int, - @Field("access_token") access_token: String, - @Field("status") status: String, - @Field("tags") tags: String, - @Field("comment") comment: String?, - @Field("rating") rating: Int, - @Field("privacy") privacy: Int = 0 - ): Call - - @FormUrlEncoded - @POST("/oauth/access_token") - fun accessToken(@Field("code") code : String, - @Field("redirect_uri") redirect_uri: String = REDIRECT_URL, - @Field("grant_type") grant_type : String = "authorization_code", - @Field("client_id") client_id : String = APP_ID, - @Field("client_secret") client_secret : String = APP_SECRET - ): Call - - @FormUrlEncoded - @POST("/oauth/access_token") - fun refreshToken(@Field("refresh_token") refresh_token : String, - @Field("redirect_uri") redirect_uri: String = REDIRECT_URL, - @Field("grant_type") grant_type : String = "refresh_token", - @Field("client_id") client_id : String = APP_ID, - @Field("client_secret") client_secret : String = APP_SECRET - ): Call - - /* - @FormUrlEncoded - @POST("/oauth/token_status") - fun tokenStatus(@Field("access_token") access_token : String - ): Call - */ - - @GET("/calendar") - fun calendar(): Call> - - /* - @GET("/{subject_type}/list/{username}/{collection_status}") - fun getCollectionList(@SubjectType.SubjectTypeName @Path("subject_type")subject_type: String, - @Path("username") username: String, - @CollectionStatusType.CollectionStatusType @Path("collection_status") collection_status: String, - @Query("page")page: Int = 1 - ): Call> - */ - companion object { const val SERVER = "https://bgm.tv" private const val SERVER_API = "https://api.bgm.tv" - const val APP_ID = "bgm2315af5554b7f887" - const val APP_SECRET = "adaf4941f83f2fb3c4336ee80a087f75" - const val REDIRECT_URL = "bangumi://redirect" fun createInstance(): Bangumi{ return Retrofit.Builder().baseUrl(SERVER_API) .addConverterFactory(GsonConverterFactory.create()) @@ -199,8 +93,9 @@ interface Bangumi { val infobox = doc.select("#infobox li")?.map{ val tip = it.selectFirst("span.tip")?.text()?:"" - Pair(tip.trim(':',' '), - it.text().substring(tip.length).trim()) + var value = "" + it.childNodes()?.forEach { if(it !is Element || !it.hasClass("tip")) value += it.outerHtml() } + Pair(tip.trim(':',' '), value.trim()) } var eps_count = infobox?.firstOrNull { it.first == "话数" }?.second?.toIntOrNull()?:subject.eps_count //air-date @@ -443,8 +338,8 @@ interface Bangumi { fun browserAirTime(@SubjectType.SubjectTypeName subject_type: String, year: Int, month: Int, - page: Int = 1, ua: String): Call>{ - return ApiHelper.buildHttpCall("$SERVER/$subject_type/browser/airtime/$year-$month?page=$page", mapOf("User-Agent" to ua)){ + page: Int = 1, ua: String, sub_cat: String): Call>{ + return ApiHelper.buildHttpCall("$SERVER/$subject_type/browser${if(sub_cat.isEmpty())"" else "/$sub_cat"}/airtime/$year-$month?page=$page", mapOf("User-Agent" to ua)){ val doc = Jsoup.parse(it.body()?.string()?:"") val ret = ArrayList() doc.select(".item")?.forEach{ diff --git a/app/src/main/java/soko/ekibun/bangumi/api/bangumi/bean/SubjectType.kt b/app/src/main/java/soko/ekibun/bangumi/api/bangumi/bean/SubjectType.kt index b63b5aa..0a0f06f 100644 --- a/app/src/main/java/soko/ekibun/bangumi/api/bangumi/bean/SubjectType.kt +++ b/app/src/main/java/soko/ekibun/bangumi/api/bangumi/bean/SubjectType.kt @@ -26,7 +26,8 @@ object SubjectType{ ANIME to NAME_ANIME, MUSIC to NAME_MUSIC, GAME to NAME_GAME, - REAL to NAME_REAL + REAL to NAME_REAL, + BOOK to NAME_BOOK ) @SuppressLint("SwitchIntDef") diff --git a/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/Tinygrail.kt b/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/Tinygrail.kt index c342ad5..ffeacea 100644 --- a/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/Tinygrail.kt +++ b/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/Tinygrail.kt @@ -2,6 +2,10 @@ package soko.ekibun.bangumi.api.tinygrail import org.jsoup.Jsoup import retrofit2.Call +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import retrofit2.http.GET +import retrofit2.http.Path import soko.ekibun.bangumi.api.ApiHelper import soko.ekibun.bangumi.api.bangumi.Bangumi import soko.ekibun.bangumi.api.bangumi.bean.Episode @@ -9,9 +13,19 @@ import soko.ekibun.bangumi.api.bangumi.bean.Images import soko.ekibun.bangumi.api.bangumi.bean.Subject import soko.ekibun.bangumi.api.bangumi.bean.SubjectType import soko.ekibun.bangumi.api.tinygrail.bean.OnAir +import soko.ekibun.bangumi.api.tinygrail.bean.OnAirInfo interface Tinygrail{ + @GET("/api/episode/subject/{id}") + fun onAirInfo(@Path("id") id: Int): Call + companion object { + fun createInstance(): Tinygrail{ + return Retrofit.Builder().baseUrl("https://www.tinygrail.com") + .addConverterFactory(GsonConverterFactory.create()) + .build().create(Tinygrail::class.java) + } + fun onAirList(): Call>>> { return ApiHelper.buildHttpCall("https://www.tinygrail.com/api/onair/"){ val doc = Jsoup.parse(it.body()?.string()?:"") diff --git a/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/bean/OnAirInfo.kt b/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/bean/OnAirInfo.kt new file mode 100644 index 0000000..e31b338 --- /dev/null +++ b/app/src/main/java/soko/ekibun/bangumi/api/tinygrail/bean/OnAirInfo.kt @@ -0,0 +1,14 @@ +package soko.ekibun.bangumi.api.tinygrail.bean + +data class OnAirInfo( + val State: Int = 0, + val Value: List? = null +){ + data class EpisodeOnAirInfo( + val EpisodeId: Int = 0, + val Id: Int = 0, + val Link: String = "", + val Name: String = "", + val Site: String = "" + ) +} \ No newline at end of file diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/collection/SubjectTypeView.kt b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/collection/SubjectTypeView.kt index 6e89acc..871230d 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/collection/SubjectTypeView.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/collection/SubjectTypeView.kt @@ -23,10 +23,10 @@ class SubjectTypeView(view: TextView, onChange:()->Unit){ } init{ - view.text = SubjectType.getDescription(typeList[selectedType]?.first?:0) + val popup = PopupMenu(view.context, view) + popup.menuInflater.inflate(R.menu.list_collection_type, popup.menu) + view.text = popup.menu.findItem(selectedType)?.title view.setOnClickListener { - val popup = PopupMenu(view.context, view) - popup.menuInflater.inflate(R.menu.list_collection_type, popup.menu) popup.setOnMenuItemClickListener{ selectedType = it.itemId view.text = it.title diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/timeline/TimeLineFragment.kt b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/timeline/TimeLineFragment.kt index 75d8945..a7423c9 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/timeline/TimeLineFragment.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/home/fragment/timeline/TimeLineFragment.kt @@ -23,10 +23,10 @@ class TimeLineFragment: HomeTabFragment(R.layout.fragment_timeline){ val adapter = TimeLinePagerAdapter(view.context, this, item_pager) item_pager?.adapter = adapter item_tabs?.setupWithViewPager(item_pager) - item_type?.text = "好友" + val popup = PopupMenu(view.context, item_type) + popup.menuInflater.inflate(R.menu.list_timeline, popup.menu) + item_type?.text = popup.menu.findItem(adapter.selectedType)?.title item_type?.setOnClickListener { - val popup = PopupMenu(view.context, item_type) - popup.menuInflater.inflate(R.menu.list_timeline, popup.menu) popup.menu.findItem(R.id.timeline_type_self)?.isVisible = ((activity as? MainActivity)?.user?.username?:"").isNotEmpty() popup.setOnMenuItemClickListener{ item_type?.text = it.title diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexPagerAdapter.kt b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexPagerAdapter.kt index dc6c5a0..5051568 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexPagerAdapter.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexPagerAdapter.kt @@ -15,12 +15,11 @@ import soko.ekibun.bangumi.api.ApiHelper import soko.ekibun.bangumi.api.bangumi.Bangumi import soko.ekibun.bangumi.api.bangumi.bean.Subject import soko.ekibun.bangumi.ui.main.MainActivity -import soko.ekibun.bangumi.ui.main.fragment.home.fragment.collection.SubjectTypeView import soko.ekibun.bangumi.ui.subject.SubjectActivity import java.util.* class IndexPagerAdapter(private val fragment: IndexFragment, private val pager: ViewPager): RecyclePagerAdapter() { - private val subjectTypeView = SubjectTypeView(fragment.item_type) { + private val indexTypeView = IndexTypeView(fragment.item_type) { pageIndex.clear() pager.adapter?.notifyDataSetChanged() } @@ -32,6 +31,8 @@ class IndexPagerAdapter(private val fragment: IndexFragment, private val pager: private val pageIndex = SparseIntArray() private var indexCalls = WeakHashMap>>() private fun loadIndex(item: IndexPagerViewHolder){ + val indexType = IndexTypeView.typeList[indexTypeView.selectedType]?:return + val position = item.position val year = position/12 + 1000 val month = position % 12 + 1 @@ -41,7 +42,7 @@ class IndexPagerAdapter(private val fragment: IndexFragment, private val pager: item.adapter.setNewData(null) item.view.isRefreshing = true } - indexCalls[position] = Bangumi.browserAirTime(subjectTypeView.getTypeName(), year, month, page + 1, (fragment.activity as? MainActivity)?.ua?:"") + indexCalls[position] = Bangumi.browserAirTime(indexType.first, year, month, page + 1, (fragment.activity as? MainActivity)?.ua?:"", indexType.second) item.adapter.isUseEmpty(false) indexCalls[position]?.enqueue(ApiHelper.buildCallback(item.view.context, { item.adapter.isUseEmpty(true) diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexTypeView.kt b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexTypeView.kt new file mode 100644 index 0000000..fbde86a --- /dev/null +++ b/app/src/main/java/soko/ekibun/bangumi/ui/main/fragment/index/IndexTypeView.kt @@ -0,0 +1,76 @@ +package soko.ekibun.bangumi.ui.main.fragment.index + +import android.support.v7.widget.PopupMenu +import android.widget.TextView +import soko.ekibun.bangumi.R +import soko.ekibun.bangumi.api.bangumi.bean.SubjectType + +class IndexTypeView(view: TextView, onChange:()->Unit){ + companion object { + val typeList = mapOf( + R.id.collection_type_anime_all to Pair(SubjectType.NAME_ANIME, ""), + R.id.collection_type_anime_tv to Pair(SubjectType.NAME_ANIME, "tv"), + R.id.collection_type_anime_web to Pair(SubjectType.NAME_ANIME, "web"), + R.id.collection_type_anime_ova to Pair(SubjectType.NAME_ANIME, "ova"), + R.id.collection_type_anime_movie to Pair(SubjectType.NAME_ANIME, "movie"), + R.id.collection_type_anime_misc to Pair(SubjectType.NAME_ANIME, "misc"), + R.id.collection_type_book_all to Pair(SubjectType.NAME_BOOK, ""), + R.id.collection_type_book_comic to Pair(SubjectType.NAME_BOOK, "comic"), + R.id.collection_type_book_novel to Pair(SubjectType.NAME_BOOK, "novel"), + R.id.collection_type_book_illustration to Pair(SubjectType.NAME_BOOK, "illustration"), + R.id.collection_type_book_misc to Pair(SubjectType.NAME_BOOK, "misc"), + R.id.collection_type_game_all to Pair(SubjectType.NAME_GAME, ""), + R.id.collection_type_game_pc to Pair(SubjectType.NAME_GAME, "pc"), + R.id.collection_type_game_mac to Pair(SubjectType.NAME_GAME, "mac"), + R.id.collection_type_game_ps4 to Pair(SubjectType.NAME_GAME, "ps4"), + R.id.collection_type_game_xbox_one to Pair(SubjectType.NAME_GAME, "xbox_one"), + R.id.collection_type_game_ns to Pair(SubjectType.NAME_GAME, "ns"), + R.id.collection_type_game_wii_u to Pair(SubjectType.NAME_GAME, "wii_u"), + R.id.collection_type_game_ps3 to Pair(SubjectType.NAME_GAME, "ps3"), + R.id.collection_type_game_xbox360 to Pair(SubjectType.NAME_GAME, "xbox360"), + R.id.collection_type_game_wii to Pair(SubjectType.NAME_GAME, "wii"), + R.id.collection_type_game_psv to Pair(SubjectType.NAME_GAME, "psv"), + R.id.collection_type_game_3ds to Pair(SubjectType.NAME_GAME, "3ds"), + R.id.collection_type_game_iphone to Pair(SubjectType.NAME_GAME, "iphone"), + R.id.collection_type_game_android to Pair(SubjectType.NAME_GAME, "android"), + R.id.collection_type_game_arc to Pair(SubjectType.NAME_GAME, "arc"), + R.id.collection_type_game_nds to Pair(SubjectType.NAME_GAME, "nds"), + R.id.collection_type_game_psp to Pair(SubjectType.NAME_GAME, "psp"), + R.id.collection_type_game_ps2 to Pair(SubjectType.NAME_GAME, "ps2"), + R.id.collection_type_game_xbox to Pair(SubjectType.NAME_GAME, "xbox"), + R.id.collection_type_game_gamecube to Pair(SubjectType.NAME_GAME, "gamecube"), + R.id.collection_type_game_dreamcast to Pair(SubjectType.NAME_GAME, "dreamcast"), + R.id.collection_type_game_n64 to Pair(SubjectType.NAME_GAME, "n64"), + R.id.collection_type_game_ps to Pair(SubjectType.NAME_GAME, "ps"), + R.id.collection_type_game_sfc to Pair(SubjectType.NAME_GAME, "sfc"), + R.id.collection_type_game_fc to Pair(SubjectType.NAME_GAME, "fc"), + R.id.collection_type_game_ws to Pair(SubjectType.NAME_GAME, "ws"), + R.id.collection_type_game_wsc to Pair(SubjectType.NAME_GAME, "wsc"), + R.id.collection_type_game_ngp to Pair(SubjectType.NAME_GAME, "ngp"), + R.id.collection_type_game_GBA to Pair(SubjectType.NAME_GAME, "GBA"), + R.id.collection_type_game_vb to Pair(SubjectType.NAME_GAME, "vb"), + R.id.collection_type_music to Pair(SubjectType.NAME_MUSIC, ""), + R.id.collection_type_real_all to Pair(SubjectType.NAME_REAL, ""), + R.id.collection_type_real_jp to Pair(SubjectType.NAME_REAL, "jp"), + R.id.collection_type_real_en to Pair(SubjectType.NAME_REAL, "en"), + R.id.collection_type_real_cn to Pair(SubjectType.NAME_REAL, "cn")) + } + var selectedType = R.id.collection_type_anime_all + + init{ + val popup = PopupMenu(view.context, view) + popup.menuInflater.inflate(R.menu.list_browser_type, popup.menu) + view.text = popup.menu.findItem(selectedType)?.title?.toString()?.replace("全部", "") + view.setOnClickListener { + popup.setOnMenuItemClickListener{ + if(typeList.containsKey(it.itemId)){ + selectedType = it.itemId + view.text = it.title.toString().replace("全部", "") + onChange() + } + true + } + popup.show() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/search/SearchTypeView.kt b/app/src/main/java/soko/ekibun/bangumi/ui/search/SearchTypeView.kt index d2e2f09..ecd6e40 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/search/SearchTypeView.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/search/SearchTypeView.kt @@ -22,14 +22,11 @@ class SearchTypeView(view: TextView, onChange:()->Unit){ var selectedType = R.id.collection_type_all init{ - view.text = mapOf(R.id.collection_type_mono to "人物", - R.id.collection_type_ctr to "虚构角色", - R.id.collection_type_psn to "现实人物")[selectedType]?:SubjectType.getDescription(subjectTypeList[selectedType]?:0) - + val context = ContextThemeWrapper(view.context, R.style.AppTheme_PopupOverlay) + val popup = PopupMenu(context, view) + popup.menuInflater.inflate(R.menu.list_search_type, popup.menu) + view.text = popup.menu.findItem(selectedType)?.title view.setOnClickListener { - val context = ContextThemeWrapper(view.context, R.style.AppTheme_PopupOverlay) - val popup = PopupMenu(context, view) - popup.menuInflater.inflate(R.menu.list_search_type, popup.menu) popup.setOnMenuItemClickListener{ selectedType = it.itemId view.text = it.title diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectActivity.kt b/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectActivity.kt index 2bd540e..afe529c 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectActivity.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectActivity.kt @@ -28,7 +28,7 @@ class SubjectActivity : SwipeBackActivity() { title="" subjectPresenter.init(JsonUtil.toEntity(intent.getStringExtra(SubjectActivity.EXTRA_SUBJECT)?:"", Subject::class.java)?: { - val id = Regex("""/subject/([0-9]+)""").find(intent.data!!.toString())!!.groupValues[1].toInt() + val id = Regex("""/subject/([0-9]+)""").find(intent.data?.toString()?:"")?.groupValues?.get(1)?.toIntOrNull()?:0 Subject(id, "${Bangumi.SERVER}/subject/$id") }()) } diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectPresenter.kt b/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectPresenter.kt index ffa14da..e508c73 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectPresenter.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectPresenter.kt @@ -5,8 +5,10 @@ import android.app.Dialog import android.net.Uri import android.support.customtabs.CustomTabsIntent import android.support.v7.app.AlertDialog +import android.support.v7.widget.LinearLayoutManager import android.view.* import android.widget.PopupMenu +import android.widget.TextView import kotlinx.android.synthetic.main.activity_subject.* import kotlinx.android.synthetic.main.activity_subject.view.* import kotlinx.android.synthetic.main.dialog_epsode.view.* @@ -22,6 +24,8 @@ import soko.ekibun.bangumi.api.bangumi.bean.* import soko.ekibun.bangumi.api.bangumi.bean.Collection import soko.ekibun.bangumi.api.github.GithubRaw import soko.ekibun.bangumi.api.github.bean.BangumiItem +import soko.ekibun.bangumi.api.tinygrail.Tinygrail +import soko.ekibun.bangumi.api.tinygrail.bean.OnAirInfo import soko.ekibun.bangumi.api.trim21.BgmIpViewer import soko.ekibun.bangumi.api.trim21.bean.IpView import soko.ekibun.bangumi.ui.web.WebActivity @@ -185,6 +189,19 @@ class SubjectPresenter(private val context: SubjectActivity){ view.item_episode_title.setOnClickListener { WebActivity.launchUrl(context, "${Bangumi.SERVER}/m/topic/ep/${episode.id}", "") } + val adapter = SitesAdapter(onAirInfo?.Value?.filter { it.EpisodeId == episode.id }?.map{BangumiItem.SitesBean(it.Site, it.Name, it.Link)}?.toMutableList()) + val emptyTextView = TextView(context) + val dp4 = (context.resources.displayMetrics.density * 4 + 0.5f).toInt() + emptyTextView.setPadding(dp4,dp4,dp4,dp4) + emptyTextView.text = "暂无播放源" + adapter.emptyView = emptyTextView + adapter.setOnItemClickListener { _, _, position -> + WebActivity.launchUrl(context, adapter.data[position].url, "") + } + view.item_site_list.adapter = adapter + val linearLayoutManager = LinearLayoutManager(context) + linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL + view.item_site_list.layoutManager = linearLayoutManager when(episode.progress?.status?.id?:0){ 1 -> view.radio_queue.isChecked = true 2 -> view.radio_watch.isChecked = true @@ -315,6 +332,7 @@ class SubjectPresenter(private val context: SubjectActivity){ subjectView.commentAdapter.loadMoreFail()})) } + var onAirInfo: OnAirInfo? = null; private fun refreshLines(subject: Subject){ val dateList = subject.air_date?.split("-") ?: return val year = dateList.getOrNull(0)?.toIntOrNull()?:0 @@ -328,6 +346,10 @@ class SubjectPresenter(private val context: SubjectActivity){ } subjectView.detail.site_list.visibility = if(subjectView.sitesAdapter.data.isEmpty()) View.GONE else View.VISIBLE }, {})) + + Tinygrail.createInstance().onAirInfo(subject.id).enqueue(ApiHelper.buildCallback(context, { + onAirInfo = it + }, {})) } private fun removeCollection(subject: Subject){ diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectView.kt b/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectView.kt index e28df20..23b99ae 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectView.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/subject/SubjectView.kt @@ -9,7 +9,10 @@ import android.support.v7.app.AlertDialog import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.support.v7.widget.StaggeredGridLayoutManager +import android.text.Html +import android.text.method.LinkMovementMethod import android.view.Gravity +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.animation.AnimationUtils @@ -21,6 +24,7 @@ import com.xiaofeng.flowlayoutmanager.FlowLayoutManager import jp.wasabeef.glide.transformations.BlurTransformation import kotlinx.android.synthetic.main.activity_subject.* import kotlinx.android.synthetic.main.activity_subject.view.* +import kotlinx.android.synthetic.main.dialog_infobox.view.* import kotlinx.android.synthetic.main.subject_blog.* import kotlinx.android.synthetic.main.subject_buttons.* import kotlinx.android.synthetic.main.subject_character.* @@ -28,15 +32,19 @@ import kotlinx.android.synthetic.main.subject_detail.* import kotlinx.android.synthetic.main.subject_episode.* import kotlinx.android.synthetic.main.subject_episode.view.* import kotlinx.android.synthetic.main.subject_topic.* +import org.jsoup.Jsoup import soko.ekibun.bangumi.R import soko.ekibun.bangumi.api.bangumi.Bangumi import soko.ekibun.bangumi.api.bangumi.bean.* import soko.ekibun.bangumi.ui.main.fragment.calendar.CalendarAdapter +import soko.ekibun.bangumi.ui.topic.PostAdapter.Companion.setTextLinkOpenByWebView import soko.ekibun.bangumi.ui.view.DragPhotoView import soko.ekibun.bangumi.ui.web.WebActivity import soko.ekibun.bangumi.util.AppUtil +import soko.ekibun.bangumi.util.HttpUtil import soko.ekibun.bangumi.util.JsonUtil import soko.ekibun.bangumi.util.PlayerBridge +import java.net.URI class SubjectView(private val context: SubjectActivity){ val episodeAdapter = SmallEpisodeAdapter() @@ -182,9 +190,9 @@ class SubjectView(private val context: SubjectActivity){ val saleDate = subject.infobox?.firstOrNull { it.first in arrayOf("发售日期", "发售日", "发行日期") } val artist = subject.infobox?.firstOrNull { it.first.substringBefore(" ") in arrayOf("动画制作", "作者", "开发", "游戏制作", "艺术家") } ?:subject.infobox?.firstOrNull { it.first.substringBefore(" ") in arrayOf("导演", "发行") } - context.item_air_time.text = if(saleDate!= null) "${saleDate.first}:${saleDate.second}" + context.item_air_time.text = if(saleDate!= null) "${saleDate.first}:${Jsoup.parse(saleDate.second).body().text()}" else "放送日期:${subject.air_date?:""} ${if(artist != null)CalendarAdapter.weekSmall[subject.air_weekday] else ""}" - context.item_air_week.text = if(artist != null) "${artist.first}:${artist.second}" else "更新时间:${CalendarAdapter.weekSmall[subject.air_weekday]}" + context.item_air_week.text = if(artist != null) "${artist.first}:${Jsoup.parse(artist.second).body().text()}" else "更新时间:${CalendarAdapter.weekSmall[subject.air_weekday]}" detail.item_detail.text = subject.summary context.item_play.visibility = if(PlayerBridge.checkActivity(context) && subject.type in listOf(SubjectType.ANIME, SubjectType.REAL)) View.VISIBLE else View.GONE @@ -255,10 +263,17 @@ class SubjectView(private val context: SubjectActivity){ } detail.item_detail.setOnClickListener { - if(subject.infobox?.isNotEmpty() == true) + if(subject.infobox?.isNotEmpty() == true) { + val view = LayoutInflater.from(context).inflate(R.layout.dialog_infobox, detail, false) + @Suppress("DEPRECATION") + view.item_infobox_text.text = setTextLinkOpenByWebView(Html.fromHtml(subject.infobox?.map { "${it.first}: ${it.second}" }?.reduce { acc, s -> "$acc
$s" })){ + WebActivity.launchUrl(context, HttpUtil.getUrl(it, URI.create(Bangumi.SERVER)), "") + } + view.item_infobox_text.movementMethod = LinkMovementMethod.getInstance() AlertDialog.Builder(context) - .setMessage(subject.infobox?.map{"${it.first}: ${it.second}"}?.reduce { acc, s -> "$acc\n$s" }) + .setView(view) .show() + } else WebActivity.launchUrl(context, subject.url) } diff --git a/app/src/main/java/soko/ekibun/bangumi/ui/web/WebActivity.kt b/app/src/main/java/soko/ekibun/bangumi/ui/web/WebActivity.kt index 9c3a0d8..40fe070 100644 --- a/app/src/main/java/soko/ekibun/bangumi/ui/web/WebActivity.kt +++ b/app/src/main/java/soko/ekibun/bangumi/ui/web/WebActivity.kt @@ -6,7 +6,6 @@ import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.net.Uri -import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.KeyEvent @@ -20,10 +19,11 @@ import soko.ekibun.bangumi.api.bangumi.Bangumi import soko.ekibun.bangumi.api.bangumi.bean.Subject import soko.ekibun.bangumi.ui.subject.SubjectActivity import soko.ekibun.bangumi.ui.topic.TopicActivity +import soko.ekibun.bangumi.ui.view.SwipeBackActivity import soko.ekibun.bangumi.util.AppUtil import java.net.URI -class WebActivity : AppCompatActivity() { +class WebActivity : SwipeBackActivity() { private val isAuth by lazy{ intent.getBooleanExtra(IS_AUTH, false)} private val openUrl by lazy{ intent.getStringExtra(OPEN_URL)} @@ -107,18 +107,24 @@ class WebActivity : AppCompatActivity() { } //back - private fun processBack(){ + override fun processBack(){ when { webview.canGoBack() -> webview.goBack() else -> { if(isAuth) setResult(Activity.RESULT_CANCELED, null) - finish() + super.processBack() } } } override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (keyCode == KeyEvent.KEYCODE_BACK){ - processBack() + when { + webview.canGoBack() -> webview.goBack() + else -> { + if(isAuth) setResult(Activity.RESULT_CANCELED, null) + finish() + } + } return true } return super.onKeyDown(keyCode, event) @@ -170,6 +176,7 @@ class WebActivity : AppCompatActivity() { val host = try{ URI.create(url).host }catch (e: Exception){ return false } + if(host.isNullOrEmpty()) return false bgmHosts.forEach { if(host.contains(it)) return true } diff --git a/app/src/main/res/layout/dialog_epsode.xml b/app/src/main/res/layout/dialog_epsode.xml index fcf3c4a..ba45596 100644 --- a/app/src/main/res/layout/dialog_epsode.xml +++ b/app/src/main/res/layout/dialog_epsode.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:colorBackground" - android:paddingBottom="12dp" android:orientation="vertical"> + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_infobox.xml b/app/src/main/res/layout/dialog_infobox.xml new file mode 100644 index 0000000..2a378ac --- /dev/null +++ b/app/src/main/res/layout/dialog_infobox.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_subject.xml b/app/src/main/res/layout/item_subject.xml index b8f7a41..be612fa 100644 --- a/app/src/main/res/layout/item_subject.xml +++ b/app/src/main/res/layout/item_subject.xml @@ -42,7 +42,7 @@ android:paddingStart="4dp" android:paddingEnd="4dp" android:background="@drawable/bg_round_rect" - android:text="已追番" + android:text="已收藏" android:backgroundTint="?colorAccent" app:layout_constraintLeft_toLeftOf="@+id/item_name_jp" app:layout_constraintTop_toTopOf="@+id/item_title" diff --git a/app/src/main/res/menu/list_browser_type.xml b/app/src/main/res/menu/list_browser_type.xml new file mode 100644 index 0000000..06e331c --- /dev/null +++ b/app/src/main/res/menu/list_browser_type.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file