From 5670ece56daa9a909380e4dcec371fc3cd54316b Mon Sep 17 00:00:00 2001 From: lunaticbum Date: Thu, 18 Sep 2025 17:55:44 +0900 Subject: [PATCH] ... --- .../bums/lunatic/launcher/BookmarkUploader.kt | 236 ++++++++++++++++++ .../bums/lunatic/launcher/home/GeckoWeb.kt | 189 +++++++++++++- .../lunatic/launcher/utils/CommonUtils.kt | 1 - app/src/main/res/layout/dialog_login.xml | 32 +++ test_image.jpg | Bin 0 -> 107989 bytes 5 files changed, 444 insertions(+), 14 deletions(-) create mode 100644 app/src/main/kotlin/bums/lunatic/launcher/BookmarkUploader.kt create mode 100644 app/src/main/res/layout/dialog_login.xml create mode 100644 test_image.jpg diff --git a/app/src/main/kotlin/bums/lunatic/launcher/BookmarkUploader.kt b/app/src/main/kotlin/bums/lunatic/launcher/BookmarkUploader.kt new file mode 100644 index 00000000..cdd05079 --- /dev/null +++ b/app/src/main/kotlin/bums/lunatic/launcher/BookmarkUploader.kt @@ -0,0 +1,236 @@ +package bums.lunatic.launcher + +// ui/bookmark/BookmarkUploader.kt + +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.MultipartBody +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.RequestBody.Companion.toRequestBody +import okhttp3.logging.HttpLoggingInterceptor + +object OkHttpClientInstance { + + val client: OkHttpClient by lazy { + // 네트워크 로그를 보기 위한 인터셉터 설정 + val loggingInterceptor = HttpLoggingInterceptor().apply { + level = HttpLoggingInterceptor.Level.BODY + } + + OkHttpClient.Builder() + .addInterceptor(loggingInterceptor) + .build() + } +} + +object BookmarkUploader { + + // 로그인 성공 시 서버로부터 받은 JWT 토큰을 저장할 변수 + val isUserLoggedIn: Boolean + get() = userJwtToken != null + + private var userJwtToken: String? = null + + private val baseUrl = "https://lunaticbum.kr" + private val loginUrl = "$baseUrl/api/auth/login" + private val saveBookmarkUrl = "$baseUrl/bookmarks" + private val saveBookmarkWithImageUrl = "$baseUrl/api/bookmarks/with-image" + + /** + * 로그인 API를 호출하여 JWT 토큰을 받아오는 함수 (콜백 추가) + * @param onSuccess 로그인 성공 시 실행될 콜백 함수 + * @param onError 로그인 실패 시 실행될 콜백 함수 + */ + fun loginAndGetToken( + userId: String, + userPw: String, + onSuccess: () -> Unit, + onError: (String) -> Unit + ) { + CoroutineScope(Dispatchers.IO).launch { + try { + val loginDataMap = mapOf("userId" to userId, "userPw" to userPw) + val json = Gson().toJson(loginDataMap) + val requestBody = json.toRequestBody("application/json; charset=utf-8".toMediaType()) + val request = Request.Builder().url(loginUrl).post(requestBody).build() + + val responseJson = OkHttpClientInstance.client.newCall(request).execute().use { response -> + if (!response.isSuccessful) { + throw Exception("로그인 실패: ${response.code} ${response.message}") + } + response.body?.string() + } + + if (responseJson != null) { + val type = object : TypeToken>() {}.type + val resultMap: Map = Gson().fromJson(responseJson, type) + userJwtToken = resultMap["token"] + + if (userJwtToken != null) { + println("✅ 로그인 성공! 토큰을 발급받았습니다.") + withContext(Dispatchers.Main) { onSuccess() } // 성공 콜백 실행 + } else { + val errorMessage = "❌ 로그인 실패: 응답에 토큰이 없습니다." + println(errorMessage) + withContext(Dispatchers.Main) { onError(errorMessage) } // 실패 콜백 실행 + } + } + } catch (e: Exception) { + val errorMessage = "🔥 로그인 중 오류 발생: ${e.message}" + println(errorMessage) + withContext(Dispatchers.Main) { onError(errorMessage) } // 실패 콜백 실행 + } + } + } + + /** + * OkHttpClient를 사용해 새 북마크를 서버에 저장하는 함수 + */ + fun saveBookmarkWithOkHttp(url: String, + selectedImageUrl: String?, comment: String, visibility: String) { + // 토큰이 없으면 함수를 실행하지 않음 (로그인 필요) + if (userJwtToken == null) { + println("🛑 저장을 위해 로그인이 필요합니다.") + // TODO: 사용자에게 로그인하라는 메시지 표시 + return + } + + CoroutineScope(Dispatchers.IO).launch { + try { + val bookmarkDataMap = mutableMapOf( + "url" to url, + "userComment" to comment, + "visibility" to visibility + ) + + if (selectedImageUrl != null) { + bookmarkDataMap["userSelectedImageUrl"] = selectedImageUrl + } + val json = Gson().toJson(bookmarkDataMap) + val requestBody = json.toRequestBody("application/json; charset=utf-8".toMediaType()) + + // "Bearer " 접두사를 포함한 인증 토큰 준비 + val formattedToken = "Bearer $userJwtToken" + + val request = Request.Builder() + .url(saveBookmarkUrl) + .addHeader("Authorization", formattedToken) // 인증 헤더 추가 + .post(requestBody) + .build() + + val responseJson = withContext(Dispatchers.IO) { + OkHttpClientInstance.client.newCall(request).execute().use { response -> + if (!response.isSuccessful) { + throw Exception("API 호출 실패: ${response.code} ${response.message}") + } + response.body?.string() + } + } + + if (responseJson != null) { + val type = object : TypeToken>() {}.type + val resultMap: Map = Gson().fromJson(responseJson, type) + println("✅ 북마크 저장 성공: $resultMap") + } else { + println("❌ 북마크 저장 실패: 응답 본문이 비어있습니다.") + } + + } catch (e: Exception) { + println("🔥 북마크 저장 중 오류 발생: ${e.message}") + } + } + } + + + + fun saveBookmarkWithImageUpload( + pageUrl: String, + selectedImageUrl: String, + comment: String, + visibility: String + ) { + if (userJwtToken == null) { + println("🛑 저장을 위해 로그인이 필요합니다.") + return + } + + CoroutineScope(Dispatchers.IO).launch { + try { + // --- 1단계: 이미지 다운로드 (pageUrl을 referer로 전달) --- + val imageData = downloadImage(selectedImageUrl, pageUrl) // referer 추가 + if (imageData == null) { + println("❌ 이미지 다운로드 실패") + return@launch + } + + // --- 2단계: Multipart 요청 생성 및 업로드 (기존과 동일) --- + val bookmarkDataMap = mapOf( + "url" to pageUrl, + "userComment" to comment, + "visibility" to visibility + ) + val bookmarkDataJson = Gson().toJson(bookmarkDataMap) + + val multipartBody = MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("bookmarkData", bookmarkDataJson) + .addFormDataPart( + "imageFile", + "user_selected_image.jpg", + imageData.toRequestBody("image/jpeg".toMediaTypeOrNull()) + ) + .build() + + val formattedToken = "Bearer $userJwtToken" + val request = Request.Builder() + .url(saveBookmarkWithImageUrl) + .addHeader("Authorization", formattedToken) + .post(multipartBody) + .build() + + // 백그라운드에서 API 호출 + withContext(Dispatchers.IO) { + OkHttpClientInstance.client.newCall(request).execute().use { response -> + if (response.isSuccessful) { + println("✅ 이미지와 함께 북마크 저장 성공: ${response.body?.string()}") + } else { + println("❌ 이미지와 함께 북마-크 저장 실패: ${response.code}") + } + } + } + + } catch (e: Exception) { + println("🔥 북마크 저장(이미지 포함) 중 오류 발생: ${e.message}") + } + } + } + + /** + * 주어진 URL에서 이미지를 다운로드하여 ByteArray로 반환하는 헬퍼 함수 (Referer 추가) + */ + private suspend fun downloadImage(imageUrl: String, referer: String?): ByteArray? = withContext(Dispatchers.IO) { + try { + val requestBuilder = Request.Builder().url(imageUrl) + // referer가 있으면 헤더에 추가 + if (referer != null) { + requestBuilder.addHeader("Referer", referer) + } + val request = requestBuilder.build() + + OkHttpClientInstance.client.newCall(request).execute().use { response -> + if (!response.isSuccessful) return@withContext null + response.body?.bytes() + } + } catch (e: Exception) { + println("🔥 이미지 다운로드 중 예외 발생: ${e.message}") + null + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt index 953163a8..21b590d6 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/home/GeckoWeb.kt @@ -30,13 +30,17 @@ import android.view.PointerIcon import android.view.View import android.widget.CheckBox import android.widget.EditText +import android.widget.LinearLayout import android.widget.ProgressBar +import android.widget.RadioButton +import android.widget.RadioGroup import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat.getSystemService import androidx.core.net.toUri import androidx.core.view.isVisible +import bums.lunatic.launcher.BookmarkUploader import bums.lunatic.launcher.LauncherActivity.Companion.getRuntime import bums.lunatic.launcher.R import bums.lunatic.launcher.model.Dotax @@ -47,6 +51,7 @@ import bums.lunatic.launcher.tokiz.view.BWebview import bums.lunatic.launcher.utils.Blog import bums.lunatic.launcher.utils.CommonUtils import bums.lunatic.launcher.workers.WorkersDb +import com.google.android.material.textfield.TextInputEditText import com.google.gson.Gson import com.vladsch.flexmark.html2md.converter.FlexmarkHtmlConverter import com.yausername.youtubedl_android.YoutubeDL @@ -485,6 +490,124 @@ class GeckoWeb : BWebview { super.onExternalResponse(session, response) } + private fun startBookmarkSaveProcess(pageUrl: String, mediaUrl: String) { + // 1. 로그인 상태 확인 + if (BookmarkUploader.isUserLoggedIn) { + // 이미 로그인 되어 있으면, 바로 북마크 정보 입력창 표시 + showBookmarkDetailsDialog(pageUrl, mediaUrl) + } else { + // 로그인이 안 되어 있으면, 로그인 창을 먼저 표시 + showLoginDialog { + // 로그인 성공 시 콜백으로 북마크 정보 입력창 표시 + showBookmarkDetailsDialog(pageUrl, mediaUrl) + } + } + } + + /** + * 사용자에게 로그인을 요청하는 다이얼로그를 표시하는 함수 + * @param onLoginSuccess 로그인 성공 시 실행될 콜백 함수 + */ + private fun showLoginDialog(onLoginSuccess: () -> Unit) { + val view = LayoutInflater.from(context).inflate(R.layout.dialog_login, null) // dialog_login.xml 레이아웃 필요 + val userIdInput = view.findViewById(R.id.et_user_id) + val userPwInput = view.findViewById(R.id.et_user_pw) + + AlertDialog.Builder(context) + .setTitle("로그인 필요") + .setMessage("북마크를 저장하려면 로그인이 필요합니다.") + .setView(view) + .setPositiveButton("로그인") { dialog, _ -> + val userId = userIdInput.text.toString().trim() + val userPw = userPwInput.text.toString().trim() + + if (userId.isNotEmpty() && userPw.isNotEmpty()) { + // 입력된 정보로 로그인 시도 + BookmarkUploader.loginAndGetToken( + userId = userId, + userPw = userPw, + onSuccess = { + Toast.makeText(context, "로그인 성공!", Toast.LENGTH_SHORT).show() + onLoginSuccess() // 로그인 성공 콜백 실행 + }, + onError = { errorMessage -> + Toast.makeText(context, "로그인 실패: $errorMessage", Toast.LENGTH_LONG).show() + } + ) + } else { + Toast.makeText(context, "아이디와 비밀번호를 모두 입력해주세요.", Toast.LENGTH_SHORT).show() + } + } + .setNegativeButton("취소", null) + .show() + } + + /** + * 북마크 저장을 위해 사용자로부터 코멘트와 공개 여부를 입력받는 다이얼로그 (수정된 버전) + */ + private fun showBookmarkDetailsDialog(pageUrl: String, mediaUrl: String) { + val context = this@GeckoWeb.context ?: return + val visibilityOptions = arrayOf("PUBLIC", "MEMBERS", "PRIVATE") + + // --- UI 요소들을 담을 컨테이너 레이아웃 --- + val containerLayout = LinearLayout(context).apply { + orientation = LinearLayout.VERTICAL + val padding = (20 * resources.displayMetrics.density).toInt() // 패딩 값 조정 + setPadding(padding, padding, padding, padding) + } + + // --- 1. 코멘트 입력 EditText --- + val commentInput = EditText(context).apply { + hint = "코멘트를 입력하세요 (선택)" + } + containerLayout.addView(commentInput) // 컨테이너에 추가 + + // --- 2. 공개 범위 선택 RadioGroup --- + val radioGroup = RadioGroup(context).apply { + orientation = RadioGroup.VERTICAL + val marginTop = (16 * resources.displayMetrics.density).toInt() + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ).apply { + this.topMargin = marginTop + } + } + + // visibilityOptions 배열을 기반으로 라디오 버튼 동적 생성 + visibilityOptions.forEachIndexed { index, option -> + val radioButton = RadioButton(context).apply { + text = option + id = index // 각 라디오 버튼에 고유 ID 부여 + } + radioGroup.addView(radioButton) + } + radioGroup.check(0) // 첫 번째 옵션(PUBLIC)을 기본값으로 선택 + + containerLayout.addView(radioGroup) // 컨테이너에 RadioGroup 추가 + + + // --- 다이얼로그 생성 --- + AlertDialog.Builder(context) + .setTitle("북마크 저장") + .setView(containerLayout) // 직접 만든 레이아웃을 View로 설정 + .setPositiveButton("저장") { _, _ -> + val comment = commentInput.text.toString() + + // 선택된 라디오 버튼의 텍스트를 가져와 visibility로 사용 + val checkedRadioButtonId = radioGroup.checkedRadioButtonId + val visibility = (radioGroup.findViewById(checkedRadioButtonId))?.text.toString() + + if (visibility.isNotEmpty()) { + BookmarkUploader.saveBookmarkWithImageUpload(pageUrl, mediaUrl, comment, visibility) + Toast.makeText(context, "[$visibility] 북마크로 저장했습니다.", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(context, "공개 범위가 선택되지 않았습니다.", Toast.LENGTH_SHORT).show() + } + } + .setNegativeButton("취소", null) + .show() + } override fun onContextMenu( session: GeckoSession, @@ -493,6 +616,45 @@ class GeckoWeb : BWebview { element: GeckoSession.ContentDelegate.ContextElement ) { + + val pageUrl = element.baseUri ?: lastedUrl ?: return // 페이지 URL + var mediaUrl = element.srcUri ?: return // 이미지 또는 비디오 URL + + // 컨텍스트 메뉴에 '북마크 저장' 옵션 추가 + val menuItems = mutableListOf() + val isMediaElement = element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_IMAGE || + element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_VIDEO + + if (isMediaElement) { + menuItems.add("이 미디어 북마크하기") + menuItems.add("이 미디어 다운로드하기") + } + + if (menuItems.isEmpty()) { + super.onContextMenu(session, screenX, screenY, element) + return + } + fun show(pageUrl : String,mediaUrl : String) { + AlertDialog.Builder(context) + .setTitle("작업 선택") + .setItems(menuItems.toTypedArray()) { _, which -> + when (menuItems[which]) { + "이 미디어 북마크하기" -> { + // 북마크 저장 프로세스 시작 + startBookmarkSaveProcess(pageUrl, mediaUrl) + } + "이 미디어 다운로드하기" -> { + // 기존의 파일 다운로드 로직 실행 + val finalMediaUrl = if (mediaUrl.contains("dcimg")) replaceDcUrl(mediaUrl) else mediaUrl + CommonUtils.downloadFileWithOkHttp(context, Uri.parse(pageUrl), finalMediaUrl) + } + } + } + .show() + } + + + if (element.baseUri?.contains("youtube") == true) { // lastedUrl?.let { videoUrl -> // lastedUrl?.let { @@ -501,20 +663,21 @@ class GeckoWeb : BWebview { // } } else { Blog.LOGE("onContextMenu:: x = ${x}, y = ${y} , element = ${Gson().toJson(element)}") - if (element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_IMAGE) { - element.srcUri?.let { - (if (it.contains("dcimg")){ replaceDcUrl(it) } else { element.srcUri })?.let { - - CommonUtils.downloadFileWithOkHttp(context, Uri.parse(element.baseUri), it) +// if (!BookmarkUploader.isUserLoggedIn) { + BookmarkUploader.loginAndGetToken( + userId = "lunaticbum", + userPw = "VioPup*383", + onSuccess = { + show(pageUrl, mediaUrl) + Toast.makeText(context, "로그인 성공!", Toast.LENGTH_SHORT).show() + }, + onError = { errorMessage -> + Toast.makeText(context, "로그인 실패: $errorMessage", Toast.LENGTH_LONG).show() } - } - }else if (element.type == GeckoSession.ContentDelegate.ContextElement.TYPE_VIDEO) { - element.srcUri?.let { - (if (it.contains("dcimg")){ replaceDcUrl(it) } else { element.srcUri })?.let { - CommonUtils.downloadFileWithOkHttp(context, Uri.parse(element.baseUri), it) - } - } - } + ) +// } else { +//// show(pageUrl, mediaUrl) +// } } super.onContextMenu(session, screenX, screenY, element) } diff --git a/app/src/main/kotlin/bums/lunatic/launcher/utils/CommonUtils.kt b/app/src/main/kotlin/bums/lunatic/launcher/utils/CommonUtils.kt index 8e585d71..54258935 100644 --- a/app/src/main/kotlin/bums/lunatic/launcher/utils/CommonUtils.kt +++ b/app/src/main/kotlin/bums/lunatic/launcher/utils/CommonUtils.kt @@ -190,7 +190,6 @@ object CommonUtils { } Blog.LOGE("downloadFileWithOkHttp File saved: ${resultFile.absolutePath}") - withContext(Dispatchers.Main) { android.widget.Toast.makeText( context, diff --git a/app/src/main/res/layout/dialog_login.xml b/app/src/main/res/layout/dialog_login.xml new file mode 100644 index 00000000..586415c5 --- /dev/null +++ b/app/src/main/res/layout/dialog_login.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test_image.jpg b/test_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fca200bd23da2fc09c62593e8c661f1b53fcfd71 GIT binary patch literal 107989 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