Initial commit - v1.1.9

This commit is contained in:
2026-02-22 12:03:04 +09:00
commit 27339dc7b7
180 changed files with 12908 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
package com.example.shiftalarm
import android.os.Bundle
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.example.shiftalarm.databinding.ActivityNoticeBinding
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class NoticeActivity : AppCompatActivity() {
private lateinit var binding: ActivityNoticeBinding
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
binding = ActivityNoticeBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
supportActionBar?.hide()
binding.btnCloseNotice.setOnClickListener {
finish()
}
binding.noticeRecyclerView.layoutManager = LinearLayoutManager(this)
fetchChangelog()
}
private fun fetchChangelog() {
// GitHub Raw URL with cache busting
val baseUrl = "https://raw.githubusercontent.com/sanjeok77-tech/dakjaba-releases/main/CHANGELOG.md"
val urlString = "$baseUrl?t=${System.currentTimeMillis()}"
Thread {
try {
val url = URL(urlString)
val connection = url.openConnection() as HttpURLConnection
connection.connectTimeout = 5000
connection.readTimeout = 5000
connection.requestMethod = "GET"
connection.useCaches = false
if (connection.responseCode == 200) {
val reader = BufferedReader(InputStreamReader(connection.inputStream))
val content = reader.use { it.readText() }
runOnUiThread {
val notices = parseChangelog(content)
binding.noticeRecyclerView.adapter = NoticeAdapter(notices)
}
} else {
throw Exception("Server returned ${connection.responseCode}")
}
} catch (e: Exception) {
e.printStackTrace()
runOnUiThread {
// Fallback to local asset
loadLocalChangelog()
}
}
}.start()
}
private fun loadLocalChangelog() {
try {
val content = assets.open("CHANGELOG.md").bufferedReader().use { it.readText() }
val notices = parseChangelog(content)
binding.noticeRecyclerView.adapter = NoticeAdapter(notices)
} catch (e: Exception) {
val empty = listOf(NoticeItem("데이터 로드 실패", "", "변경사항을 불러올 수 없습니다."))
binding.noticeRecyclerView.adapter = NoticeAdapter(empty)
}
}
private fun parseChangelog(content: String): List<NoticeItem> {
val notices = mutableListOf<NoticeItem>()
val lines = content.lines()
var currentVersion = ""
var currentDate = ""
var currentBody = StringBuilder()
for (line in lines) {
val trimmed = line.trim()
// Skip empty lines or horizontal rules (any amount of dashes)
if (trimmed.isEmpty() || trimmed.matches(Regex("-{2,}"))) continue
// Handle version headers like "## v0.7.3" or "## [0.7.3]"
if (trimmed.startsWith("## v") || trimmed.startsWith("## [")) {
// Save previous version if exists
if (currentVersion.isNotEmpty() && currentBody.isNotBlank()) {
notices.add(NoticeItem("v$currentVersion 업데이트 정보", currentDate, currentBody.toString().trim()))
}
// Parse new version (matches v0.7.3 or [0.7.3])
val versionMatch = Regex("v?([\\d.]+)").find(trimmed)
currentVersion = versionMatch?.groupValues?.getOrNull(1) ?: ""
val dateMatch = Regex("(\\d{4}-\\d{2}-\\d{2})").find(trimmed)
currentDate = dateMatch?.groupValues?.getOrNull(1) ?: ""
currentBody = StringBuilder()
} else if (trimmed.startsWith("- **") || trimmed.startsWith("* **")) {
// Content line with bold key
val cleaned = trimmed
.replace(Regex("^[-*]\\s*\\*\\*(.+?)\\*\\*:?\\s*"), "$1: ")
.replace("**", "")
currentBody.appendLine(cleaned)
} else if (trimmed.startsWith("-") || trimmed.startsWith("*")) {
// Regular bullet point
val cleaned = trimmed.replace(Regex("^[-*]\\s*"), "")
if (cleaned.length > 2) currentBody.appendLine(cleaned)
}
}
// Add last version
if (currentVersion.isNotEmpty() && currentBody.isNotBlank()) {
notices.add(NoticeItem("v$currentVersion 업데이트 정보", currentDate, currentBody.toString().trim()))
}
return notices.take(7)
}
}