diff --git a/app/src/main/java/io/legado/app/ui/book/source/debug/SourceDebugActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/debug/SourceDebugActivity.kt index b180f6b17..de2ef20e7 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/debug/SourceDebugActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/debug/SourceDebugActivity.kt @@ -12,13 +12,13 @@ import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.accentColor import io.legado.app.ui.qrcode.QrCodeActivity import io.legado.app.utils.getViewModel -import kotlinx.android.synthetic.main.activity_book_source_debug.* +import kotlinx.android.synthetic.main.activity_source_debug.* import kotlinx.android.synthetic.main.view_search.* import kotlinx.coroutines.launch import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.toast -class SourceDebugActivity : VMBaseActivity(R.layout.activity_book_source_debug) { +class SourceDebugActivity : VMBaseActivity(R.layout.activity_source_debug) { override val viewModel: SourceDebugModel get() = getViewModel(SourceDebugModel::class.java) diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/SourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/SourceEditActivity.kt index c7e6dbbf5..4eb28dcea 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/SourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/SourceEditActivity.kt @@ -79,20 +79,14 @@ class SourceEditActivity : override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_save -> { - val bookSource = getSource() - if (bookSource == null) { - toast("书源名称和URL不能为空") - } else { - viewModel.save(bookSource) { setResult(Activity.RESULT_OK); finish() } + getSource()?.let { + viewModel.save(it) { setResult(Activity.RESULT_OK); finish() } } } R.id.menu_debug_source -> { - val bookSource = getSource() - if (bookSource == null) { - toast("书源名称和URL不能为空") - } else { - viewModel.save(bookSource) { - startActivity(Pair("key", bookSource.bookSourceUrl)) + getSource()?.let { + viewModel.save(it) { + startActivity(Pair("key", it.bookSourceUrl)) } } } @@ -147,7 +141,7 @@ class SourceEditActivity : } //基本信息 sourceEntities.clear() - searchEntities.apply { + sourceEntities.apply { add(EditEntity("bookSourceUrl", bookSource?.bookSourceUrl, R.string.book_source_url)) add(EditEntity("bookSourceName", bookSource?.bookSourceName, R.string.book_source_name)) add( @@ -249,84 +243,76 @@ class SourceEditActivity : val bookInfoRule = BookInfoRule() val tocRule = TocRule() val contentRule = ContentRule() - for (entity in sourceEntities) { - with(entity) { - when (key) { - "bookSourceUrl" -> value?.let { source.bookSourceUrl = it } ?: return null - "bookSourceName" -> value?.let { source.bookSourceName = it } ?: return null - "bookSourceGroup" -> source.bookSourceGroup = value - "loginUrl" -> source.loginUrl = value - "bookUrlPattern" -> source.bookUrlPattern = value - "header" -> source.header = value - } + sourceEntities.forEach { + when (it.key) { + "bookSourceUrl" -> source.bookSourceUrl = it.value ?: "" + "bookSourceName" -> source.bookSourceName = it.value ?: "" + "bookSourceGroup" -> source.bookSourceGroup = it.value + "loginUrl" -> source.loginUrl = it.value + "bookUrlPattern" -> source.bookUrlPattern = it.value + "header" -> source.header = it.value } } - for (entity in searchEntities) { - with(entity) { - when (key) { - "searchUrl" -> source.searchUrl = value - "bookList" -> searchRule.bookList = value - "name" -> searchRule.name = value - "author" -> searchRule.author = value - "kind" -> searchRule.kind = value - "intro" -> searchRule.intro = value - "updateTime" -> searchRule.updateTime = value - "wordCount" -> searchRule.wordCount = value - "lastChapter" -> searchRule.lastChapter = value - "coverUrl" -> searchRule.coverUrl = value - "bookUrl" -> searchRule.bookUrl = value - } + if (source.bookSourceUrl.isBlank() || source.bookSourceName.isBlank()) { + toast("书源名称和URL不能为空") + return null + } + searchEntities.forEach { + when (it.key) { + "searchUrl" -> source.searchUrl = it.value + "bookList" -> searchRule.bookList = it.value + "name" -> searchRule.name = it.value + "author" -> searchRule.author = it.value + "kind" -> searchRule.kind = it.value + "intro" -> searchRule.intro = it.value + "updateTime" -> searchRule.updateTime = it.value + "wordCount" -> searchRule.wordCount = it.value + "lastChapter" -> searchRule.lastChapter = it.value + "coverUrl" -> searchRule.coverUrl = it.value + "bookUrl" -> searchRule.bookUrl = it.value } } - for (entity in findEntities) { - with(entity) { - when (key) { - "exploreUrl" -> source.exploreUrl = value - "bookList" -> exploreRule.bookList = value - "name" -> exploreRule.name = value - "author" -> exploreRule.author = value - "kind" -> exploreRule.kind = value - "intro" -> exploreRule.intro = value - "updateTime" -> exploreRule.updateTime = value - "wordCount" -> exploreRule.wordCount = value - "lastChapter" -> exploreRule.lastChapter = value - "coverUrl" -> exploreRule.coverUrl = value - "bookUrl" -> exploreRule.bookUrl = value - } + findEntities.forEach { + when (it.key) { + "exploreUrl" -> source.exploreUrl = it.value + "bookList" -> exploreRule.bookList = it.value + "name" -> exploreRule.name = it.value + "author" -> exploreRule.author = it.value + "kind" -> exploreRule.kind = it.value + "intro" -> exploreRule.intro = it.value + "updateTime" -> exploreRule.updateTime = it.value + "wordCount" -> exploreRule.wordCount = it.value + "lastChapter" -> exploreRule.lastChapter = it.value + "coverUrl" -> exploreRule.coverUrl = it.value + "bookUrl" -> exploreRule.bookUrl = it.value } } - for (entity in infoEntities) { - with(entity) { - when (key) { - "init" -> bookInfoRule.init = value - "name" -> bookInfoRule.name = value - "author" -> bookInfoRule.author = value - "kind" -> bookInfoRule.kind = value - "intro" -> bookInfoRule.intro = value - "updateTime" -> bookInfoRule.updateTime = value - "wordCount" -> bookInfoRule.wordCount = value - "lastChapter" -> bookInfoRule.lastChapter = value - "coverUrl" -> bookInfoRule.coverUrl = value - "tocUrl" -> bookInfoRule.tocUrl = value - } + infoEntities.forEach { + when (it.key) { + "init" -> bookInfoRule.init = it.value + "name" -> bookInfoRule.name = it.value + "author" -> bookInfoRule.author = it.value + "kind" -> bookInfoRule.kind = it.value + "intro" -> bookInfoRule.intro = it.value + "updateTime" -> bookInfoRule.updateTime = it.value + "wordCount" -> bookInfoRule.wordCount = it.value + "lastChapter" -> bookInfoRule.lastChapter = it.value + "coverUrl" -> bookInfoRule.coverUrl = it.value + "tocUrl" -> bookInfoRule.tocUrl = it.value } } - for (entity in tocEntities) { - with(entity) { - when (key) { - "chapterList" -> tocRule.chapterList = value - "chapterName" -> tocRule.chapterName = value - "chapterUrl" -> tocRule.chapterUrl = value - "nextTocUrl" -> tocRule.nextTocUrl = value - } + tocEntities.forEach { + when (it.key) { + "chapterList" -> tocRule.chapterList = it.value + "chapterName" -> tocRule.chapterName = it.value + "chapterUrl" -> tocRule.chapterUrl = it.value + "nextTocUrl" -> tocRule.nextTocUrl = it.value } } - for (entity in contentEntities) { - with(entity) { - when (key) { - "content" -> contentRule.content = value - "nextContentUrl" -> contentRule.nextContentUrl = value - } + contentEntities.forEach { + when (it.key) { + "content" -> contentRule.content = it.value + "nextContentUrl" -> contentRule.nextContentUrl = it.value } } source.ruleSearch = GSON.toJson(searchRule) diff --git a/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt b/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt index 347b95a23..0e0819ce5 100644 --- a/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt @@ -1,20 +1,28 @@ package io.legado.app.ui.main.rss import android.os.Bundle +import android.util.Log +import android.view.Gravity import android.view.Menu import android.view.MenuItem import android.view.View +import android.widget.EditText +import android.widget.LinearLayout import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseFragment +import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.dialogs.cancelButton +import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.ATH import io.legado.app.ui.rss.article.RssArticlesActivity import io.legado.app.ui.rss.source.manage.RssSourceActivity import io.legado.app.utils.startActivity import kotlinx.android.synthetic.main.fragment_rss.* import kotlinx.android.synthetic.main.view_title_bar.* +import org.jetbrains.anko.padding class RssFragment : BaseFragment(R.layout.fragment_rss), RssAdapter.CallBack { @@ -36,7 +44,23 @@ class RssFragment : BaseFragment(R.layout.fragment_rss), when (item.itemId) { R.id.menu_rss_config -> startActivity() R.id.menu_rss_add -> { - startActivity() + alert { + title = "快速添加并预览" + val layout = LinearLayout(activity) + val urlEdit = EditText(activity) + urlEdit.hint = "输入RSS地址" + urlEdit.width = 800 + layout.gravity = Gravity.CENTER + layout.addView(urlEdit) + customView = layout + cancelButton{ + Log.i("RSS","Quick Add URL cancel") + } + yesButton{ + Log.i("RSS","Quick Add URL: ${urlEdit.text}") + startActivity("QuickAddURL" to urlEdit.text.toString().trim()) + } + }.show() } } } diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt index 6a52df7b3..3686dacdf 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt @@ -1,5 +1,6 @@ package io.legado.app.ui.rss.article +import android.app.ProgressDialog import android.content.Context import android.os.Bundle import android.view.LayoutInflater @@ -13,68 +14,47 @@ import io.legado.app.model.rss.RssParser import io.legado.app.ui.rss.read.ReadRssActivity import kotlinx.android.synthetic.main.item_rss.view.* import org.jetbrains.anko.* -import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onItemClick import java.net.URL class RssArticlesActivity : AppCompatActivity() { - val zhihu_dayli = "https://rsshub.app/zhihu/daily" - val nytimes = "https://rsshub.app/nytimes/dual" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - var articles = mutableListOf() - val adapter = ArticleAdapter(articles, this) - verticalLayout { - val url = editText { - hint = "请输入RSS地址" - } - fun loadRss(urlString:String){ - Thread { - val xml = URL(urlString).readText() - articles = RssParser.parseXML(xml) - runOnUiThread { - adapter.articles = articles - adapter.notifyDataSetChanged() - } - }.start() - } - button("解析") { - onClick { - val urlString = url.text.toString().trim() - if(urlString != ""){ - loadRss(urlString) - } - } - } - button("知乎日报") { - onClick { - loadRss(zhihu_dayli) - } - } - button("纽约时报") { - onClick { - loadRss(nytimes) - } - } + if (intent.hasExtra("QuickAddURL")) { + // 处理从 快速添加并预览 跳转到这个页面 + val urlString = intent.getStringExtra("QuickAddURL") + val adapter = ArticleAdapter(mutableListOf(), this) listView { this.adapter = adapter onItemClick { p0, p1, p2, p3 -> - startActivity("description" to articles[p2].description) + startActivity("description" to adapter.articles[p2].description) } } + val loading = ProgressDialog(this@RssArticlesActivity) + loading.setMessage("加载中...") + loading.show() + Thread { + val xml = URL(urlString).readText() + val articles = RssParser.parseXML(xml) + runOnUiThread { + adapter.articles = articles + adapter.notifyDataSetChanged() + loading.dismiss() + } + }.start() } } } -class ArticleAdapter(var articles: List, var context: Context) : BaseAdapter() { +class ArticleAdapter(var articles: MutableList, var context: Context) : BaseAdapter() { override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { - val item_rss= LayoutInflater.from(context).inflate(R.layout.item_rss, null) + val item_rss = LayoutInflater.from(context).inflate(R.layout.item_rss, null) val article = articles[position] item_rss.title.text = article.title item_rss.pub_date.text = article.pubDate - if(article.author != null && article.author != ""){ + if (article.author != null && article.author != "") { item_rss.author.text = article.author - } else{ + } else { item_rss.author.text = article.link } return item_rss diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index 984cc0ea4..e93f1e982 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -9,7 +9,7 @@ class ReadRssActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_read_rss) - val s = intent.getStringExtra("description") - webView.loadData(""+s,"text/html","utf-8") + val description = intent.getStringExtra("description") + webView.loadData("$description","text/html", "utf-8") } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt index de8bf27dc..3018a1f1e 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugActivity.kt @@ -1,2 +1,16 @@ package io.legado.app.ui.rss.source.debug +import android.os.Bundle +import io.legado.app.R +import io.legado.app.base.BaseActivity + + +class RssSourceDebugActivity : BaseActivity(R.layout.activity_source_debug, false) { + + + override fun onActivityCreated(savedInstanceState: Bundle?) { + + } + + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt index e623420f4..79eb9552d 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt @@ -1,9 +1,14 @@ package io.legado.app.ui.rss.source.edit +import android.app.Activity +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context import android.graphics.Rect import android.os.Bundle import android.view.Gravity import android.view.Menu +import android.view.MenuItem import android.view.ViewTreeObserver import android.widget.EditText import android.widget.PopupWindow @@ -15,10 +20,13 @@ import io.legado.app.constant.AppConst import io.legado.app.data.entities.EditEntity import io.legado.app.data.entities.RssSource import io.legado.app.lib.theme.ATH +import io.legado.app.ui.rss.source.debug.RssSourceDebugActivity import io.legado.app.ui.widget.KeyboardToolPop +import io.legado.app.utils.GSON import io.legado.app.utils.getViewModel import kotlinx.android.synthetic.main.activity_book_source_edit.* import org.jetbrains.anko.displayMetrics +import org.jetbrains.anko.startActivity import kotlin.math.abs class RssSourceEditActivity : @@ -28,7 +36,7 @@ class RssSourceEditActivity : private var mSoftKeyboardTool: PopupWindow? = null private var mIsSoftKeyBoardShowing = false - private lateinit var adapter: RssSourceEditAdapter + private val adapter = RssSourceEditAdapter() private val sourceEntities: ArrayList = ArrayList() override val viewModel: RssSourceEditViewModel @@ -62,6 +70,34 @@ class RssSourceEditActivity : return super.onCompatCreateOptionsMenu(menu) } + override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.menu_save -> { + getRssSource()?.let { + viewModel.save(it) { + setResult(Activity.RESULT_OK) + finish() + } + } + } + R.id.menu_debug_source -> { + getRssSource()?.let { + viewModel.save(it) { + startActivity(Pair("key", it.sourceUrl)) + } + } + } + R.id.menu_copy_source -> { + GSON.toJson(getRssSource())?.let { sourceStr -> + val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager? + clipboard?.primaryClip = ClipData.newPlainText(null, sourceStr) + } + } + R.id.menu_paste_source -> viewModel.pasteSource() + } + return super.onCompatOptionsItemSelected(item) + } + private fun initView() { ATH.applyEdgeEffectColor(recycler_view) mSoftKeyboardTool = KeyboardToolPop(this, AppConst.keyboardToolChars, this) @@ -98,7 +134,31 @@ class RssSourceEditActivity : add(EditEntity("ruleContent", rssSource?.ruleContent, R.string.rss_rule_content)) add(EditEntity("ruleLink", rssSource?.ruleLink, R.string.rss_rule_link)) } + adapter.editEntities = sourceEntities + } + private fun getRssSource(): RssSource? { + val source = viewModel.sourceLiveData.value ?: RssSource() + sourceEntities.forEach { + when (it.key) { + "sourceName" -> source.sourceName = it.value ?: "" + "sourceUrl" -> source.sourceName = it.value ?: "" + "iconUrl" -> source.sourceName = it.value ?: "" + "ruleTitle" -> source.sourceName = it.value ?: "" + "ruleAuthor" -> source.sourceName = it.value ?: "" + "ruleGuid" -> source.sourceName = it.value ?: "" + "rulePubDate" -> source.sourceName = it.value ?: "" + "ruleCategories" -> source.sourceName = it.value ?: "" + "ruleDescription" -> source.sourceName = it.value ?: "" + "ruleImage" -> source.sourceName = it.value ?: "" + "ruleContent" -> source.sourceName = it.value ?: "" + "ruleLink" -> source.sourceName = it.value ?: "" + } + } + if (source.sourceName.isBlank() || source.sourceName.isBlank()) { + return null + } + return source } override fun sendText(text: String) { diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt index 53f7d01de..b4c0133a8 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditViewModel.kt @@ -1,10 +1,14 @@ package io.legado.app.ui.rss.source.edit import android.app.Application +import android.content.ClipboardManager +import android.content.Context import androidx.lifecycle.MutableLiveData import io.legado.app.App import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.RssSource +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonObject class RssSourceEditViewModel(application: Application) : BaseViewModel(application) { @@ -18,5 +22,25 @@ class RssSourceEditViewModel(application: Application) : BaseViewModel(applicati } } + fun save(rssSource: RssSource, success: (() -> Unit)) { + execute { + App.db.rssSourceDao().insert(rssSource) + }.onSuccess { + success() + } + } + fun pasteSource() { + execute { + val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager? + clipboard?.primaryClip?.let { + if (it.itemCount > 0) { + val json = it.getItemAt(0).text.toString() + GSON.fromJsonObject(json)?.let { source -> + sourceLiveData.postValue(source) + } ?: toast("格式不对") + } + } + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_rss_source_edit.xml b/app/src/main/res/layout/activity_rss_source_edit.xml index 5579d3de5..dd2545faf 100644 --- a/app/src/main/res/layout/activity_rss_source_edit.xml +++ b/app/src/main/res/layout/activity_rss_source_edit.xml @@ -1,6 +1,7 @@ @@ -11,6 +12,7 @@ android:layout_height="wrap_content" app:contentInsetStartWithNavigation="0dp" app:displayHomeAsUp="true" + app:fitStatusBar="false" app:title="@string/rss_source_edit" /> @@ -24,7 +24,10 @@ @@ -32,7 +35,8 @@