Skip to content

Commit

Permalink
Fixes and cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Deftu committed Jun 4, 2024
1 parent 4e659c7 commit 016a931
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 48 deletions.
16 changes: 4 additions & 12 deletions src/main/kotlin/dev/deftu/screencapper/Screencapper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,23 @@ import com.mojang.brigadier.arguments.StringArgumentType
import dev.deftu.lib.client.ClientCommandHelper
import gg.essential.universal.UDesktop
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.loader.api.FabricLoader
import net.minecraft.client.MinecraftClient
import net.minecraft.text.Text
import net.minecraft.util.Formatting
import okhttp3.OkHttpClient
import dev.deftu.lib.utils.TextHelper
import dev.deftu.screencapper.config.ScreencapperConfig
import dev.deftu.screencapper.config.ShareXConfig
import dev.deftu.screencapper.config.deftuDir
import dev.deftu.screencapper.gui.preview.ScreenshotPreview
import java.io.File

object Screencapper : ClientModInitializer {
const val NAME = "Screencapper"
const val ID = "screencapper"

val httpClient = OkHttpClient.Builder()
.addInterceptor {
it.proceed(it.request().newBuilder().addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36").build())
}.build()
val configDirectory = File(FabricLoader.getInstance().configDir.toFile(), "Deftu")
const val NAME = "@MOD_NAME@"
const val ID = "@MOD_ID@"

override fun onInitializeClient() {
ScreencapperConfig.initialize()
ShareXConfig.initialize(dev.deftu.screencapper.Screencapper.configDirectory)
ShareXConfig.initialize(deftuDir)
ScreenshotPreview.initialize()

ClientCommandHelper.register(
Expand Down Expand Up @@ -67,5 +60,4 @@ object Screencapper : ClientModInitializer {
MinecraftClient.getInstance().inGameHud.chatHud.addMessage(text)
}

fun sendMessage(message: String, prefix: Boolean = true) = dev.deftu.screencapper.Screencapper.sendMessage(TextHelper.createLiteralText(message), prefix)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ import gg.essential.vigilance.data.PropertyType
import net.minecraft.client.resource.language.I18n
import dev.deftu.screencapper.Screencapper
import dev.deftu.screencapper.gui.preview.PreviewPosition
import net.fabricmc.loader.api.FabricLoader
import java.io.File

private val configFile = File(dev.deftu.screencapper.Screencapper.configDirectory, "screencapper.toml").apply {
if (!parentFile.exists()) parentFile.mkdirs()
if (!exists()) createNewFile()
val deftuDir by lazy {
val deftuDir = File(FabricLoader.getInstance().gameDir.toFile(), "Deftu")
if (!deftuDir.exists() && !deftuDir.mkdirs())
throw IllegalStateException("Could not create Deftu directory!")

deftuDir
}

private val configFile by lazy {
File(deftuDir, "@[email protected]")
}

object ScreencapperConfig : Vigilant(
Expand Down
32 changes: 30 additions & 2 deletions src/main/kotlin/dev/deftu/screencapper/config/ShareXConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.annotations.SerializedName
import dev.deftu.lib.DeftuLib
import dev.deftu.screencapper.Screencapper
import net.fabricmc.loader.api.FabricLoader
import java.io.File
import java.util.concurrent.TimeUnit

private val legacyConfigDir by lazy {
File(FabricLoader.getInstance().configDir.toFile(), "Deftu")
}

object ShareXConfig {
private var initialized = false
private val gson = GsonBuilder()
Expand All @@ -22,7 +28,10 @@ object ShareXConfig {

fun initialize(directory: File) {
if (initialized) return

convertLegacy()
if (!directory.exists()) directory.mkdirs()

file = File(directory, "sharex.json")
DeftuLib.multithreader.schedule(this::load, 0, 5, TimeUnit.MINUTES)
initialized = true
Expand All @@ -35,9 +44,28 @@ object ShareXConfig {
}

fun load() {
if (!file.exists()) save()
if (!file.exists()) {
data = ShareXConfigData.createDefault()
save()
return
}

loadFrom(file)
}

fun convertLegacy() {
val file = File(legacyConfigDir, "sharex.json")
if (!file.exists()) return

loadFrom(file)
save()
file.delete()
}

private fun loadFrom(file: File) {
val content = JsonParser.parseString(file.readText())
if (!content.isJsonObject) throw IllegalStateException("sharex.json is not a JSON object!")
if (!content.isJsonObject) throw IllegalStateException("${file.name} is not a JSON object!")

data = gson.fromJson(content, ShareXConfigData::class.java)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import dev.deftu.screencapper.config.ScreencapperConfig
import dev.deftu.screencapper.utils.Screenshot

object ScreenshotPreview {
private val window = Window(ElementaVersion.V3)
private val window = Window(ElementaVersion.V5)

fun initialize() {
HudRenderCallback.EVENT.register { ctx, tickDelta ->
Expand All @@ -27,6 +27,6 @@ object ScreenshotPreview {
fun append(screenshot: Screenshot) {
val preview by ScreenshotPreviewComponent(screenshot)
preview childOf window
preview.animate()
preview.flashIn()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ class ScreenshotPreviewComponent(
companion object {
@JvmStatic
val COLLAPSE_ANIMATION = Animations.IN_OUT_SIN

const val FLASH_DURATION = 0.1f
const val COLLAPSE_DURATION = 0.5f
const val SWIPE_OUT_DURATION = 0.5f
}

private val image by UIImage.ofNativeImage(screenshot.image).constrain {
Expand All @@ -41,41 +44,48 @@ class ScreenshotPreviewComponent(
} effect OutlineEffect(Color.WHITE, 0.75f)
}

fun animate() {
fun flashIn() {
flash.animate {
setColorAnimation(Animations.IN_SIN, 0.1f, Color(255, 255, 255, 200).toConstraint()).onComplete {
flash.animate {
setColorAnimation(Animations.OUT_SIN, 0.1f, Color(255, 255, 255, 0).toConstraint()).onComplete {
collapse()
}
}
setColorAnimation(Animations.IN_SIN, FLASH_DURATION, Color(255, 255, 255, 200).toConstraint())
onComplete {
flashOut()
}
}
}

private fun collapse() {
animate {
val positions: Pair<XConstraint, YConstraint> = when (ScreencapperConfig.previewPosition) {
PreviewPosition.TOP_LEFT -> 2.percent to basicYConstraint { 2.percent.getXPositionImpl(it) }
PreviewPosition.TOP_RIGHT -> 68.percent to basicYConstraint { 2.percent.getXPositionImpl(it) }
PreviewPosition.BOTTOM_LEFT -> 2.percent to 0.pixels(alignOpposite = true) - basicYConstraint { 2.percent.getXPositionImpl(it) }
PreviewPosition.BOTTOM_RIGHT -> 68.percent to 0.pixels(alignOpposite = true) - basicYConstraint { 2.percent.getXPositionImpl(it) }
private fun flashOut() {
flash.animate {
setColorAnimation(Animations.OUT_SIN, FLASH_DURATION, Color(255, 255, 255, 0).toConstraint())
onComplete {
collapseDown()
}
}
}

private fun collapseDown() {
val positions: Pair<XConstraint, YConstraint> = when (ScreencapperConfig.previewPosition) {
PreviewPosition.TOP_LEFT -> 2.percent to basicYConstraint { 2.percent.getXPositionImpl(it) }
PreviewPosition.TOP_RIGHT -> 68.percent to basicYConstraint { 2.percent.getXPositionImpl(it) }
PreviewPosition.BOTTOM_LEFT -> 2.percent to 0.pixels(alignOpposite = true) - basicYConstraint { 2.percent.getXPositionImpl(it) }
PreviewPosition.BOTTOM_RIGHT -> 68.percent to 0.pixels(alignOpposite = true) - basicYConstraint { 2.percent.getXPositionImpl(it) }
}

animate {
setXAnimation(COLLAPSE_ANIMATION, COLLAPSE_DURATION, positions.first)
setYAnimation(COLLAPSE_ANIMATION, COLLAPSE_DURATION, positions.second)
setWidthAnimation(COLLAPSE_ANIMATION, COLLAPSE_DURATION, 30.percent)
setHeightAnimation(COLLAPSE_ANIMATION, COLLAPSE_DURATION, ChildBasedMaxSizeConstraint())

onComplete {
remove()
swipeOut()
}
}
}

private fun remove() {
private fun swipeOut() {
animate {
val x = if (ScreencapperConfig.previewPosition.isLeft()) (-30).percent else 100.percent
setXAnimation(Animations.OUT_SIN, 0.5f, x, ScreencapperConfig.previewTime.toFloat()).onComplete {
setXAnimation(Animations.OUT_SIN, SWIPE_OUT_DURATION, x, ScreencapperConfig.previewTime.toFloat()).onComplete {
hide()
}
}
Expand Down
17 changes: 7 additions & 10 deletions src/main/kotlin/dev/deftu/screencapper/upload/ShareXUploadTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dev.deftu.screencapper.upload
import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonParser
import dev.deftu.lib.DeftuLib
import net.minecraft.client.MinecraftClient
import net.minecraft.util.Formatting
import okhttp3.MediaType.Companion.toMediaType
Expand All @@ -21,23 +22,19 @@ import dev.deftu.screencapper.utils.Screenshot
import java.net.URL

object ShareXUploadTask {
private val gson = GsonBuilder()
.setPrettyPrinting()
.setLenient()
.create()
private val urlNameRegex = "\\\$json:(?<path>.+)\\\$".toRegex()

fun upload(screenshot: Screenshot): Screenshot {
dev.deftu.screencapper.Screencapper.sendMessage(
TextHelper.createTranslatableText("${dev.deftu.screencapper.Screencapper.ID}.text.chat.upload.sharex.start")
Screencapper.sendMessage(
TextHelper.createTranslatableText("${Screencapper.ID}.text.chat.upload.sharex.start")
.formatted(Formatting.GRAY))
var screenshot = screenshot
if (ScreencapperConfig.shareXUploadUrl.isEmpty()) {
MinecraftClient.getInstance().inGameHud.chatHud.addMessage(TextHelper.createTranslatableText("${dev.deftu.screencapper.Screencapper.ID}.error.upload_missing_url")
MinecraftClient.getInstance().inGameHud.chatHud.addMessage(TextHelper.createTranslatableText("${Screencapper.ID}.error.upload_missing_url")
.formatted(Formatting.RED))
return screenshot
}
val response = dev.deftu.screencapper.Screencapper.httpClient.newCall(Request.Builder()
val response = DeftuLib.browserHttpClient.newCall(Request.Builder()
.url(ScreencapperConfig.shareXUploadUrl)
.handleRequestBody(screenshot)
.build()).execute()
Expand Down Expand Up @@ -67,15 +64,15 @@ object ShareXUploadTask {
} else getUrl(path).asString
screenshot = Screenshot(screenshot.image, screenshot.bytes, screenshot.file, URL(url))
} else {
MinecraftClient.getInstance().inGameHud.chatHud.addMessage(TextHelper.createTranslatableText("${dev.deftu.screencapper.Screencapper.ID}.error.upload_error", response.code)
MinecraftClient.getInstance().inGameHud.chatHud.addMessage(TextHelper.createTranslatableText("${Screencapper.ID}.error.upload_error", response.code)
.formatted(Formatting.RED))
LogManager.getLogger("Screencapper (ShareX Upload)").error("""
Upload failed with code ${response.code}:
${response.message}
""".trimIndent())
}
response.close()
dev.deftu.screencapper.Screencapper.sendMessage(TextHelper.createTranslatableText("${dev.deftu.screencapper.Screencapper.ID}.text.chat.upload.sharex.end")
Screencapper.sendMessage(TextHelper.createTranslatableText("${Screencapper.ID}.text.chat.upload.sharex.end")
.formatted(Formatting.GREEN))
return screenshot
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/dev/deftu/screencapper/utils/Screenshot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.net.URL

data class Screenshot(
val image: NativeImage,
val bytes: ByteArray,
@Suppress("ArrayInDataClass") val bytes: ByteArray,
val file: File,
val url: URL? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import com.terraformersmc.modmenu.api.ModMenuApi
import dev.deftu.screencapper.config.ScreencapperConfig

class ModMenuIntegration : ModMenuApi {
override fun getModConfigScreenFactory() = ConfigScreenFactory {

override fun getModConfigScreenFactory() = ConfigScreenFactory { _ ->
ScreencapperConfig.gui()
}

}

0 comments on commit 016a931

Please sign in to comment.