From 8a6737dd5d5ed92d7ba4245417a9ba6159da21fd Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Fri, 6 Dec 2024 16:28:49 +0300 Subject: [PATCH] successfully save html --- .../myplanet/base/BaseContainerFragment.kt | 56 ++++++++++++++-- .../planet/myplanet/model/RealmMyLibrary.kt | 36 +++++++++- .../myplanet/ui/resources/AdapterResource.kt | 67 ++++++++++++++++--- .../myplanet/ui/viewer/WebViewActivity.kt | 23 +++++-- 4 files changed, 162 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt index 83545b2d85..0cc672bd5b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/base/BaseContainerFragment.kt @@ -8,6 +8,7 @@ import android.net.Uri import android.os.Bundle import android.provider.Settings import android.text.TextUtils +import android.util.Log import android.view.LayoutInflater import android.view.MotionEvent import android.view.View @@ -72,9 +73,8 @@ abstract class BaseContainerFragment : BaseResourceFragment() { AdapterCourses.showRating(`object`, rating, timesRated, ratingBar) } } - fun getUrlsAndStartDownload( - lib: List, urls: ArrayList - ) { + + fun getUrlsAndStartDownload(lib: List, urls: ArrayList) { for (library in lib) { val url = Utilities.getUrl(library) if (!FileUtils.checkFileExist(url) && !TextUtils.isEmpty(url)) urls.add(url) @@ -83,6 +83,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { activity, getString(R.string.no_images_to_download) ) } + fun initRatingView(type: String?, id: String?, title: String?, listener: OnRatingChangeListener?) { timesRated = requireView().findViewById(R.id.times_rated) rating = requireView().findViewById(R.id.tv_rating) @@ -102,12 +103,14 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } } } + override fun onAttach(context: Context) { super.onAttach(context) if (context is OnHomeItemClickListener) { homeItemClickListener = context } } + private fun openIntent(items: RealmMyLibrary, typeClass: Class<*>?) { val fileOpenIntent = Intent(activity, typeClass) if (items.resourceLocalAddress?.contains("ole/audio") == true || items.resourceLocalAddress?.contains("ole/video") == true) { @@ -119,6 +122,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } startActivity(fileOpenIntent) } + private fun openPdf(item: RealmMyLibrary) { val fileOpenIntent = Intent(activity, PDFReaderActivity::class.java) fileOpenIntent.putExtra("TOUCHED_FILE", item.id + "/" + item.resourceLocalAddress) @@ -149,10 +153,16 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } private fun checkFileExtension(items: RealmMyLibrary) { - val filenameArray = items.resourceLocalAddress?.split("\\.".toRegex())?.toTypedArray() - val extension = filenameArray?.get(filenameArray.size - 1) +// val filenameArray = items.resourceLocalAddress?.split("\\.".toRegex())?.toTypedArray() +// val extension = filenameArray?.get(filenameArray.size - 1) val mimetype = Utilities.getMimeType(items.resourceLocalAddress) val userId = "${model?.id}" + Log.d("FileExtension", "Mimetype: ${items.resourceLocalAddress}") + + val extension = items.resourceLocalAddress + ?.substringAfterLast('.', "") + ?.lowercase() + val existingAction = mRealm.where(RealmUserChallengeActions::class.java) .equalTo("userId", userId) @@ -195,12 +205,31 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } openIntent(items, TextFileViewerActivity::class.java) } + "html", "htm" -> { + if (existingAction == null) { + createAction(mRealm, userId, items.resourceId, "resourceOpen") + } + openHtmlResource(items) + } "md" -> { + // Special handling for README.md + if (items.resourceLocalAddress?.contains("README.md", ignoreCase = true) == true) { + // Optionally log or handle README.md differently + Log.d("FileExtension", "Detected README.md file") + return // Or handle it specifically + } + if (existingAction == null) { createAction(mRealm, userId, items.resourceId, "resourceOpen") } openIntent(items, MarkdownViewerActivity::class.java) } +// "md" -> { +// if (existingAction == null) { +// createAction(mRealm, userId, items.resourceId, "resourceOpen") +// } +// openIntent(items, MarkdownViewerActivity::class.java) +// } "csv" -> { if (existingAction == null) { createAction(mRealm, userId, items.resourceId, "resourceOpen") @@ -213,6 +242,12 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } installApk(items) } +// "html", "htm" -> { +// if (existingAction == null) { +// createAction(mRealm, userId, items.resourceId, "resourceOpen") +// } +// openHtmlResource(items) +// } else -> Toast.makeText(activity, getString(R.string.this_file_type_is_currently_unsupported), Toast.LENGTH_LONG).show() } } @@ -270,6 +305,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { checkFileExtension(items) } } + open fun playVideo(videoType: String, items: RealmMyLibrary) { val intent = Intent(activity, VideoPlayerActivity::class.java) val bundle = Bundle() @@ -333,6 +369,7 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } } } + fun setResourceButton(resources: List?, btnResources: Button) { if (resources.isNullOrEmpty()) { btnResources.visibility = View.GONE @@ -347,6 +384,15 @@ abstract class BaseContainerFragment : BaseResourceFragment() { } } + private fun openHtmlResource(items: RealmMyLibrary) { + val intent = Intent(activity, WebViewActivity::class.java).apply { + putExtra("TOUCHED_FILE", "${items.id}/${items.resourceLocalAddress}") + putExtra("title", items.title) + putExtra("isLocalFile", true) + } + startActivity(intent) + } + open fun handleBackPressed() { val fragmentManager = parentFragmentManager fragmentManager.popBackStack() diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt index 6b4932a791..55b5f1b7d6 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmMyLibrary.kt @@ -21,6 +21,7 @@ import java.io.FileWriter import java.io.IOException import java.util.Calendar import java.util.Date +import java.util.UUID open class RealmMyLibrary : RealmObject() { @PrimaryKey @@ -64,6 +65,8 @@ open class RealmMyLibrary : RealmObject() { var courseId: String? = null var stepId: String? = null var isPrivate: Boolean = false + var attachments: RealmList? = null + fun serializeResource(): JsonObject { return JsonObject().apply { addProperty("_id", _id) @@ -282,7 +285,25 @@ open class RealmMyLibrary : RealmObject() { description = JsonUtils.getString("description", doc) if (doc.has("_attachments")) { val attachments = doc["_attachments"].asJsonObject - attachments.entrySet().forEach { (key, _) -> + if (this.attachments == null) { + this.attachments = RealmList() + } + + attachments.entrySet().forEach { (key, attachmentValue) -> + val attachmentObj = attachmentValue.asJsonObject + + val realmAttachment = mRealm.createObject(RealmAttachment::class.java, UUID.randomUUID().toString()) + realmAttachment.apply { + name = key + contentType = attachmentObj.get("content_type")?.asString + length = attachmentObj.get("length")?.asLong ?: 0 + digest = attachmentObj.get("digest")?.asString + isStub = attachmentObj.get("stub")?.asBoolean == true + revpos = attachmentObj.get("revpos")?.asInt ?: 0 + } + + this.attachments?.add(realmAttachment) + if (key.indexOf("/") < 0) { resourceRemoteAddress = "${settings.getString("couchdbURL", "http://")}/resources/$resourceId/$key" resourceLocalAddress = key @@ -407,7 +428,7 @@ open class RealmMyLibrary : RealmObject() { @JvmStatic fun getArrayList(libraries: List, type: String): Set { - return libraries.mapNotNull { if (type == "mediums") it.mediaType else it.language }.filterNot { it.isNullOrBlank() }.toSet() + return libraries.mapNotNull { if (type == "mediums") it.mediaType else it.language }.filterNot { it.isBlank() }.toSet() } @JvmStatic @@ -424,4 +445,15 @@ open class RealmMyLibrary : RealmObject() { } } } +} + +open class RealmAttachment : RealmObject() { + @PrimaryKey + var id: String? = null + var name: String? = null + var contentType: String? = null + var length: Long = 0 + var digest: String? = null + var isStub: Boolean = false + var revpos: Int = 0 } \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/resources/AdapterResource.kt b/app/src/main/java/org/ole/planet/myplanet/ui/resources/AdapterResource.kt index a259a71a4a..ff523d7846 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/resources/AdapterResource.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/resources/AdapterResource.kt @@ -2,6 +2,7 @@ package org.ole.planet.myplanet.ui.resources import android.content.Context import android.text.TextUtils +import android.util.Log import android.view.LayoutInflater import android.view.MotionEvent import android.view.View @@ -19,6 +20,7 @@ import org.ole.planet.myplanet.callback.OnLibraryItemSelected import org.ole.planet.myplanet.callback.OnRatingChangeListener import org.ole.planet.myplanet.databinding.RowLibraryBinding import org.ole.planet.myplanet.model.RealmMyLibrary +import org.ole.planet.myplanet.model.RealmMyLibrary.Companion.logLargeString import org.ole.planet.myplanet.model.RealmTag import org.ole.planet.myplanet.model.RealmUserModel import org.ole.planet.myplanet.service.UserProfileDbHandler @@ -83,19 +85,67 @@ class AdapterResource(private val context: Context, private var libraryList: Lis } holder.rowLibraryBinding.tvDate.text = libraryList[position]?.createdDate?.let { formatDate(it, "MMM dd, yyyy") } displayTagCloud(holder.rowLibraryBinding.flexboxDrawable, position) - holder.itemView.setOnClickListener { openLibrary(libraryList[position]) } + holder.itemView.setOnClickListener { + openLibrary(libraryList[position]) + val libraryItem = realm.where(RealmMyLibrary::class.java) + .equalTo("id", libraryList[position]?.id) + .findFirst() + Log.d("AdapterResource", "onBindViewHolder: $libraryItem") + libraryItem?.let { item -> + val allDetails = """ + _id: ${item._id} + _rev: ${item._rev} + Title: ${item.title} + Author: ${item.author} + Year: ${item.year} + Description: ${item.description} + Language: ${item.language} + Publisher: ${item.publisher} + Link to License: ${item.linkToLicense} + Subjects: ${item.subject?.joinToString()} + Levels: ${item.level?.joinToString()} + Resource Type: ${item.resourceType} + Open With: ${item.openWith} + Media Type: ${item.mediaType} + Article Date: ${item.articleDate} + Resource For: ${item.resourceFor?.joinToString()} + Added By: ${item.addedBy} + Upload Date: ${item.uploadDate} + Created Date: ${item.createdDate} + Resource Remote Address: ${item.resourceRemoteAddress} + Resource Local Address: ${item.resourceLocalAddress} + Resource Offline: ${item.resourceOffline} + Resource ID: ${item.resourceId} + Downloaded Rev: ${item.downloadedRev} + Needs Optimization: ${item.needsOptimization} + Tags: ${item.tag?.joinToString()} + Languages: ${item.languages?.joinToString()} + Course ID: ${item.courseId} + Step ID: ${item.stepId} + Is Private: ${item.isPrivate} + User ID: ${item.userId?.joinToString()} + Filename: ${item.filename} + Translations Audio Path: ${item.translationAudioPath} + Average Rating: ${item.averageRating} + Times Rated: ${item.timesRated} + Sum: ${item.sum} + attachment: ${item.attachments?.joinToString()} + """.trimIndent() + + logLargeString("AdapterResource", "Full Library Item Details:\n$allDetails") + } + } userModel = UserProfileDbHandler(context).userModel if (libraryList[position]?.isResourceOffline() == true) { holder.rowLibraryBinding.ivDownloaded.visibility = View.INVISIBLE } else { holder.rowLibraryBinding.ivDownloaded.visibility = View.VISIBLE } - holder.rowLibraryBinding.ivDownloaded.contentDescription = - if (libraryList[position]?.isResourceOffline() == true) { - context.getString(R.string.view) - } else { - context.getString(R.string.download) - } + holder.rowLibraryBinding.ivDownloaded.contentDescription = if (libraryList[position]?.isResourceOffline() == true) { + context.getString(R.string.view) + } else { + context.getString(R.string.download) + } if (ratingMap.containsKey(libraryList[position]?.resourceId)) { val `object` = ratingMap[libraryList[position]?.resourceId] AdapterCourses.showRating(`object`, holder.rowLibraryBinding.rating, holder.rowLibraryBinding.timesRated, holder.rowLibraryBinding.ratingBar) @@ -105,8 +155,7 @@ class AdapterResource(private val context: Context, private var libraryList: Lis if (userModel?.isGuest() == false) { holder.rowLibraryBinding.checkbox.setOnClickListener { view: View -> - holder.rowLibraryBinding.checkbox.contentDescription = - context.getString(R.string.select_res_course, libraryList[position]?.title) + holder.rowLibraryBinding.checkbox.contentDescription = context.getString(R.string.select_res_course, libraryList[position]?.title) Utilities.handleCheck((view as CheckBox).isChecked, position, selectedItems, libraryList) if (listener != null) listener?.onSelectedListChange(selectedItems) } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/viewer/WebViewActivity.kt b/app/src/main/java/org/ole/planet/myplanet/ui/viewer/WebViewActivity.kt index 01af74e9b1..a847dda0de 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/viewer/WebViewActivity.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/viewer/WebViewActivity.kt @@ -12,13 +12,16 @@ import android.webkit.WebSettings import android.webkit.WebView import android.webkit.WebViewClient import androidx.appcompat.app.AppCompatActivity +import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.databinding.ActivityWebViewBinding import org.ole.planet.myplanet.utilities.Utilities +import java.io.File class WebViewActivity : AppCompatActivity() { private lateinit var activityWebViewBinding: ActivityWebViewBinding private var fromDeepLink = false private lateinit var link: String + private var isLocalFile = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -28,11 +31,15 @@ class WebViewActivity : AppCompatActivity() { fromDeepLink = !TextUtils.isEmpty(dataFromDeepLink) val title: String? = intent.getStringExtra("title") link = intent.getStringExtra("link") ?: "" - Log.d("WebViewActivity", "onCreate: $link") + isLocalFile = intent.getBooleanExtra("isLocalFile", false) + + Log.d("WebViewActivity", "onCreate: $link, isLocalFile: $isLocalFile") clearCookie() + if (!TextUtils.isEmpty(title)) { activityWebViewBinding.contentWebView.webTitle.text = title } + activityWebViewBinding.contentWebView.pBar.max = 100 activityWebViewBinding.contentWebView.pBar.progress = 0 setListeners() @@ -45,11 +52,19 @@ class WebViewActivity : AppCompatActivity() { builtInZoomControls = true } - val headers = mapOf("Authorization" to Utilities.header) - // activityWebViewBinding.contentWebView.wv.settings.javaScriptEnabled = true // activityWebViewBinding.contentWebView.wv.settings.javaScriptCanOpenWindowsAutomatically = true - activityWebViewBinding.contentWebView.wv.loadUrl(link, headers) + if (isLocalFile) { + val touchedFile = intent.getStringExtra("TOUCHED_FILE") + if (!touchedFile.isNullOrEmpty()) { + val localFilePath = File(MainApplication.context.getExternalFilesDir(null), touchedFile).absolutePath + activityWebViewBinding.contentWebView.wv.loadUrl("file://$localFilePath") + } + } else { + // Existing remote URL loading logic + val headers = mapOf("Authorization" to Utilities.header) + activityWebViewBinding.contentWebView.wv.loadUrl(link, headers) + } activityWebViewBinding.contentWebView.finish.setOnClickListener { finish() } setWebClient() }