From fa659c7da0ca362c65c122b5ffda6cc8053587a2 Mon Sep 17 00:00:00 2001 From: rebelonion <87634197+rebelonion@users.noreply.github.com> Date: Sun, 12 May 2024 06:01:51 -0500 Subject: [PATCH] feat: creating activities in app --- app/src/main/AndroidManifest.xml | 2 + app/src/main/java/ani/dantotsu/Functions.kt | 5 +- .../connections/anilist/AnilistMutations.kt | 22 ++++ .../java/ani/dantotsu/media/ReviewActivity.kt | 11 ++ .../java/ani/dantotsu/others/SpoilerPlugin.kt | 13 ++- .../ani/dantotsu/profile/ProfileActivity.kt | 10 ++ .../dantotsu/util/MarkdownCreatorActivity.kt | 96 ++++++++++++++++ .../res/layout/activity_markdown_creator.xml | 104 ++++++++++++++++++ app/src/main/res/menu/menu_profile.xml | 5 + app/src/main/res/values/strings.xml | 4 + 10 files changed, 266 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/ani/dantotsu/util/MarkdownCreatorActivity.kt create mode 100644 app/src/main/res/layout/activity_markdown_creator.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 930cdf195ec..68841a8d690 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -198,6 +198,8 @@ + diff --git a/app/src/main/java/ani/dantotsu/Functions.kt b/app/src/main/java/ani/dantotsu/Functions.kt index d985a221c25..57419e43497 100644 --- a/app/src/main/java/ani/dantotsu/Functions.kt +++ b/app/src/main/java/ani/dantotsu/Functions.kt @@ -1399,7 +1399,8 @@ fun Context.getThemeColor(@AttrRes attribute: Int): Int { fun buildMarkwon( activity: Context, userInputContent: Boolean = true, - fragment: Fragment? = null + fragment: Fragment? = null, + anilist: Boolean = false ): Markwon { val glideContext = fragment?.let { Glide.with(it) } ?: Glide.with(activity) val markwon = Markwon.builder(activity) @@ -1415,7 +1416,7 @@ fun buildMarkwon( .usePlugin(StrikethroughPlugin.create()) .usePlugin(TablePlugin.create(activity)) .usePlugin(TaskListPlugin.create(activity)) - .usePlugin(SpoilerPlugin()) + .usePlugin(SpoilerPlugin(anilist)) .usePlugin(HtmlPlugin.create { plugin -> if (userInputContent) { plugin.addHandler( diff --git a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistMutations.kt b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistMutations.kt index e1e3b1d5732..fda763efb09 100644 --- a/app/src/main/java/ani/dantotsu/connections/anilist/AnilistMutations.kt +++ b/app/src/main/java/ani/dantotsu/connections/anilist/AnilistMutations.kt @@ -3,6 +3,9 @@ package ani.dantotsu.connections.anilist import ani.dantotsu.connections.anilist.Anilist.executeQuery import ani.dantotsu.connections.anilist.api.FuzzyDate import ani.dantotsu.connections.anilist.api.Query +import ani.dantotsu.currContext +import com.google.gson.Gson +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject class AnilistMutations { @@ -76,4 +79,23 @@ class AnilistMutations { val query = "mutation{RateReview(reviewId:$reviewId,rating:$rating){id mediaId mediaType summary body(asHtml:true)rating ratingAmount userRating score private siteUrl createdAt updatedAt user{id name bannerImage avatar{medium large}}}}" return executeQuery(query) } + + suspend fun postActivity(text:String): String { + val encodedText = Gson().toJson(text) + val query = "mutation{SaveTextActivity(text:$encodedText){siteUrl}}" + val result = executeQuery(query) + val errors = result?.get("errors") + return errors?.toString() + ?: (currContext()?.getString(ani.dantotsu.R.string.success) ?: "Success") + } + + suspend fun postReview(summary: String, body: String, mediaId: Int, score: Int): String { + val encodedSummary = Gson().toJson(summary) + val encodedBody = Gson().toJson(body) + val query = "mutation{SaveReview(mediaId:$mediaId,summary:$encodedSummary,body:$encodedBody,score:$score){siteUrl}}" + val result = executeQuery(query) + val errors = result?.get("errors") + return errors?.toString() + ?: (currContext()?.getString(ani.dantotsu.R.string.success) ?: "Success") + } } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/media/ReviewActivity.kt b/app/src/main/java/ani/dantotsu/media/ReviewActivity.kt index 453617787d6..b4631db47da 100644 --- a/app/src/main/java/ani/dantotsu/media/ReviewActivity.kt +++ b/app/src/main/java/ani/dantotsu/media/ReviewActivity.kt @@ -8,6 +8,7 @@ import android.view.MotionEvent import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.lifecycle.lifecycleScope @@ -21,6 +22,7 @@ import ani.dantotsu.navBarHeight import ani.dantotsu.profile.FollowerItem import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager +import ani.dantotsu.util.MarkdownCreatorActivity import com.xwray.groupie.GroupieAdapter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -54,6 +56,15 @@ class ReviewActivity : AppCompatActivity() { } binding.followerGrid.visibility = View.GONE binding.followerList.visibility = View.GONE + binding.followFilterButton.setImageResource(R.drawable.ic_add) + binding.followFilterButton.setOnClickListener { + ContextCompat.startActivity( + this, + Intent(this, MarkdownCreatorActivity::class.java) + .putExtra("type", "review"), + null + ) + } binding.followFilterButton.visibility = View.GONE binding.listTitle.text = getString(R.string.reviews) binding.listRecyclerView.adapter = adapter diff --git a/app/src/main/java/ani/dantotsu/others/SpoilerPlugin.kt b/app/src/main/java/ani/dantotsu/others/SpoilerPlugin.kt index 79b6138a2c6..8cb584d6c26 100644 --- a/app/src/main/java/ani/dantotsu/others/SpoilerPlugin.kt +++ b/app/src/main/java/ani/dantotsu/others/SpoilerPlugin.kt @@ -12,9 +12,13 @@ import io.noties.markwon.AbstractMarkwonPlugin import io.noties.markwon.utils.ColorUtils import java.util.regex.Pattern -class SpoilerPlugin : AbstractMarkwonPlugin() { +class SpoilerPlugin(private val anilist: Boolean = false) : AbstractMarkwonPlugin() { override fun beforeSetText(textView: TextView, markdown: Spanned) { - applySpoilerSpans(markdown as Spannable) + if (anilist) { + applySpoilerSpans(markdown as Spannable, ARE) + } else { + applySpoilerSpans(markdown as Spannable) + } } private class RedditSpoilerSpan : CharacterStyle() { @@ -45,9 +49,10 @@ class SpoilerPlugin : AbstractMarkwonPlugin() { companion object { private val RE = Pattern.compile("\\|\\|.+?\\|\\|") - private fun applySpoilerSpans(spannable: Spannable) { + private val ARE = Pattern.compile("~!.+?!~") + private fun applySpoilerSpans(spannable: Spannable, regex: Pattern = RE) { val text = spannable.toString() - val matcher = RE.matcher(text) + val matcher = regex.matcher(text) while (matcher.find()) { val spoilerSpan = RedditSpoilerSpan() val clickableSpan: ClickableSpan = object : ClickableSpan() { diff --git a/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt b/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt index 2b0d44c005c..578db05482c 100644 --- a/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt +++ b/app/src/main/java/ani/dantotsu/profile/ProfileActivity.kt @@ -37,6 +37,7 @@ import ani.dantotsu.snackString import ani.dantotsu.statusBarHeight import ani.dantotsu.themes.ThemeManager import ani.dantotsu.toast +import ani.dantotsu.util.MarkdownCreatorActivity import com.google.android.material.appbar.AppBarLayout import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -154,6 +155,15 @@ class ProfileActivity : AppCompatActivity(), AppBarLayout.OnOffsetChangedListene openLinkInBrowser("https://anilist.co/user/${user.name}") true } + R.id.action_create_new_activity -> { + ContextCompat.startActivity( + context, + Intent(context, MarkdownCreatorActivity::class.java) + .putExtra("type", "activity"), + null + ) + true + } else -> false } } diff --git a/app/src/main/java/ani/dantotsu/util/MarkdownCreatorActivity.kt b/app/src/main/java/ani/dantotsu/util/MarkdownCreatorActivity.kt new file mode 100644 index 00000000000..27b94185838 --- /dev/null +++ b/app/src/main/java/ani/dantotsu/util/MarkdownCreatorActivity.kt @@ -0,0 +1,96 @@ +package ani.dantotsu.util + +import android.os.Bundle +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.updateLayoutParams +import androidx.core.widget.addTextChangedListener +import ani.dantotsu.R +import ani.dantotsu.buildMarkwon +import ani.dantotsu.connections.anilist.Anilist +import ani.dantotsu.databinding.ActivityMarkdownCreatorBinding +import ani.dantotsu.initActivity +import ani.dantotsu.navBarHeight +import ani.dantotsu.statusBarHeight +import ani.dantotsu.themes.ThemeManager +import ani.dantotsu.toast +import io.noties.markwon.editor.MarkwonEditor +import io.noties.markwon.editor.MarkwonEditorTextWatcher +import kotlinx.coroutines.DelicateCoroutinesApi +import tachiyomi.core.util.lang.launchIO +import java.util.Locale + +class MarkdownCreatorActivity : AppCompatActivity() { + private lateinit var binding: ActivityMarkdownCreatorBinding + private lateinit var type: String + private var text: String = "" + @OptIn(DelicateCoroutinesApi::class) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + ThemeManager(this).applyTheme() + initActivity(this) + binding = ActivityMarkdownCreatorBinding.inflate(layoutInflater) + binding.markdownCreatorToolbar.updateLayoutParams { + topMargin = statusBarHeight + } + binding.buttonContainer.updateLayoutParams { + bottomMargin += navBarHeight + } + setContentView(binding.root) + if (intent.hasExtra("type")) { + type = intent.getStringExtra("type")!! + } else { + finish() + } + binding.markdownCreatorTitle.text = when (type) { + "activity" -> getString(R.string.create_new_activity) + "review" -> getString(R.string.create_new_review) + else -> "" + } + binding.editText.setText(text) + binding.editText.addTextChangedListener { + if (!binding.markdownCreatorPreviewCheckbox.isChecked) { + text = it.toString() + } + } + previewMarkdown(false) + binding.markdownCreatorPreviewCheckbox.setOnClickListener { + previewMarkdown(binding.markdownCreatorPreviewCheckbox.isChecked) + } + binding.cancelButton.setOnClickListener { + onBackPressedDispatcher.onBackPressed() + } + binding.markdownCreatorBack.setOnClickListener { + onBackPressedDispatcher.onBackPressed() + } + + binding.createButton.setOnClickListener { + launchIO { + val success = when (type) { + "activity" -> Anilist.mutation.postActivity(text) + //"review" -> Anilist.mutation.postReview(text) + else -> "Error: Unknown type" + } + toast(success) + } + onBackPressedDispatcher.onBackPressed() + } + + binding.editText.requestFocus() + } + + private fun previewMarkdown(preview: Boolean) { + val markwon = buildMarkwon(this, false, anilist = true) + if (preview) { + binding.editText.isEnabled = false + markwon.setMarkdown(binding.editText, text) + } else { + binding.editText.setText(text) + binding.editText.isEnabled = true + val markwonEditor = MarkwonEditor.create(markwon) + binding.editText.addTextChangedListener( + MarkwonEditorTextWatcher.withProcess(markwonEditor) + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_markdown_creator.xml b/app/src/main/res/layout/activity_markdown_creator.xml new file mode 100644 index 00000000000..be4a5f0ad04 --- /dev/null +++ b/app/src/main/res/layout/activity_markdown_creator.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + +