Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Gimoji Columns #60

Merged
merged 2 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 7 additions & 47 deletions src/main/kotlin/com/github/patou/gitmoji/GitCommitAction.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.github.patou.gitmoji

import com.github.patou.gitmoji.Gitmojis.Companion.insertAt
import com.google.gson.Gson
import com.intellij.ide.TextCopyProvider
import com.intellij.ide.util.PropertiesComponent
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.PlatformDataKeys
Expand All @@ -30,19 +29,14 @@ import com.intellij.util.ObjectUtils.sentinel
import com.intellij.util.containers.nullize
import com.intellij.util.ui.JBUI.scale
import com.intellij.vcs.commit.message.CommitMessageInspectionProfile.getSubjectRightMargin
import okhttp3.*
import okhttp3.Request.Builder
import java.awt.Point
import java.io.IOException
import javax.swing.JList
import javax.swing.ListSelectionModel

class GitCommitAction : AnAction() {
private val gitmojis = ArrayList<GitmojiData>()

init {
isEnabledInModalContext = true
loadGitmojiFromHTTP()
}

private val regexPattern = ":[a-z0-9_]+:"
Expand All @@ -56,12 +50,13 @@ class GitCommitAction : AnAction() {
val commitMessage = getCommitMessage(actionEvent)
when {
commitMessage != null && project != null -> {
createPopup(project, commitMessage, gitmojis)
createPopup(project, commitMessage, Gitmojis.gitmojis)
.showInBestPositionFor(actionEvent.dataContext)
}
}
}

@Suppress("MissingActionUpdateThread")
private fun createPopup(
project: Project,
commitMessage: CommitMessage,
Expand All @@ -73,7 +68,7 @@ class GitCommitAction : AnAction() {
val previewCommandGroup = sentinel("Preview Commit Message")
val projectInstance = PropertiesComponent.getInstance(project)
val displayEmoji =
projectInstance.getValue(CONFIG_DISPLAY_ICON, Gitmojis.defaultDisplayType()) == "emoji"
projectInstance.getValue(CONFIG_DISPLAY_ICON, defaultDisplayType()) == "emoji"
val currentCommitMessage = commitMessage.editorField.text
val currentOffset = commitMessage.editorField.caretModel.offset

Expand Down Expand Up @@ -172,7 +167,7 @@ class GitCommitAction : AnAction() {
var replaced = false
if (!insertInCarretPosition) {
if (useUnicode) {
for (moji in gitmojis) {
for (moji in Gitmojis.gitmojis) {
if (message.contains("${moji.emoji}$textAfterUnicode")) {
message = message.replaceFirst(
"${moji.emoji}$textAfterUnicode",
Expand Down Expand Up @@ -224,43 +219,8 @@ class GitCommitAction : AnAction() {
private fun getCommitMessage(e: AnActionEvent) =
e.getData(VcsDataKeys.COMMIT_MESSAGE_CONTROL) as? CommitMessage

private fun loadGitmojiFromHTTP() {
val client = OkHttpClient().newBuilder().addInterceptor(SafeGuardInterceptor()).build()
val request: Request = Builder()
.url("https://gitmoji.dev/api/gitmojis")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
loadDefaultGitmoji()
}

override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) loadDefaultGitmoji()
else {
loadGitmoji(response.body!!.string())
}
}
}
})
}

private fun loadDefaultGitmoji() {
javaClass.getResourceAsStream("/gitmojis.json").use { inputStream ->
if (inputStream != null) {
val text = inputStream.bufferedReader().readText()
loadGitmoji(text)
}
}
}

private fun loadGitmoji(text: String) {
Gson().fromJson(text, Gitmojis::class.java).also {
it.gitmojis.forEach { gitmoji ->
gitmojis.add(GitmojiData(gitmoji.code, gitmoji.emoji, gitmoji.description, gitmoji.name))
}
}
GitmojiLocale.loadTranslations()
override fun getActionUpdateThread(): ActionUpdateThread {
return ActionUpdateThread.BGT
}

}
2 changes: 1 addition & 1 deletion src/main/kotlin/com/github/patou/gitmoji/GitMojiConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class GitMojiConfig(private val project: Project) : SearchableConfigurable {
val propertiesComponent = PropertiesComponent.getInstance(project)
val instance = PropertiesComponent.getInstance()

displayEmojiConfig = propertiesComponent.getValue(CONFIG_DISPLAY_ICON, Gitmojis.defaultDisplayType())
displayEmojiConfig = propertiesComponent.getValue(CONFIG_DISPLAY_ICON, defaultDisplayType())
useUnicodeConfig = propertiesComponent.getBoolean(CONFIG_USE_UNICODE, false)
insertInCursorPositionConfig = propertiesComponent.getBoolean(CONFIG_INSERT_IN_CURSOR_POSITION, false)
includeGitMojiDescriptionConfig = propertiesComponent.getBoolean(CONFIG_INCLUDE_GITMOJI_DESCRIPTION, false)
Expand Down
25 changes: 25 additions & 0 deletions src/main/kotlin/com/github/patou/gitmoji/GitmojiCellRenderer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.github.patou.gitmoji

import com.intellij.vcs.log.ui.table.VcsLogGraphTable
import com.intellij.vcs.log.ui.table.VcsLogIconCellRenderer

class GitmojiCellRenderer : VcsLogIconCellRenderer() {
override fun customize(
table: VcsLogGraphTable,
value: Any?,
selected: Boolean,
hasFocus: Boolean,
row: Int,
column: Int
) {
if (value == null || value !is GitmojiData) {
return
}
if (value.name == "anguished") {
append("-")
return
}
icon = value.getIcon()
toolTipText = value.localeDescription
}
}
47 changes: 47 additions & 0 deletions src/main/kotlin/com/github/patou/gitmoji/GitmojiCustomColumn.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.github.patou.gitmoji

import com.intellij.ide.util.PropertiesComponent
import com.intellij.openapi.project.ProjectManager
import com.intellij.vcs.log.ui.table.GraphTableModel
import com.intellij.vcs.log.ui.table.VcsLogGraphTable
import com.intellij.vcs.log.ui.table.column.VcsLogCustomColumn
import javax.swing.table.TableCellRenderer


@Suppress("UnstableApiUsage")
class GitmojiCustomColumn : VcsLogCustomColumn<GitmojiData> {
override val id: String
get() = "gitmoji"
override val isDynamic: Boolean
get() = true
override val localizedName: String
get() = "Gitmoji"
override val isResizable: Boolean
get() = false

override fun createTableCellRenderer(table: VcsLogGraphTable): TableCellRenderer {
return GitmojiCellRenderer()
}

override fun isEnabledByDefault(): Boolean {
val projectInstance = PropertiesComponent.getInstance(ProjectManager.getInstance().defaultProject)
val useUnicode = projectInstance.getBoolean(CONFIG_USE_UNICODE, false)
return useUnicode
}

override fun getStubValue(model: GraphTableModel): GitmojiData {
return GitmojiData("anguished", "😧", "anguished", "anguished")
}

override fun getValue(model: GraphTableModel, row: Int): GitmojiData? {
model.getCommitMetadata(row).let {
for (moji in Gitmojis.gitmojis) {
if (it.subject.contains(moji.emoji) || it.subject.contains(moji.code)) {
return moji
}
}
}
return null
}

}
26 changes: 26 additions & 0 deletions src/main/kotlin/com/github/patou/gitmoji/GitmojiUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.github.patou.gitmoji

import com.intellij.openapi.util.SystemInfo

fun defaultDisplayType(): String {
return if (SystemInfo.isWindows) "icon" else "emoji"
}

fun insertAt(target: String, position: Int, insert: String): String {
val targetLen = target.length
require(!(position < 0 || position > targetLen)) { "position=$position" }
if (insert.isEmpty()) {
return target
}
if (position == 0) {
return insert + target
} else if (position == targetLen) {
return target + insert
}
val insertLen = insert.length
val buffer = CharArray(targetLen + insertLen)
target.toCharArray(buffer, 0, 0, position)
insert.toCharArray(buffer, position, 0, insertLen)
target.toCharArray(buffer, position + insertLen, position, targetLen)
return String(buffer)
}
68 changes: 45 additions & 23 deletions src/main/kotlin/com/github/patou/gitmoji/Gitmojis.kt
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
package com.github.patou.gitmoji

import com.intellij.openapi.util.SystemInfo
import com.google.gson.Gson
import okhttp3.*
import okhttp3.Request.Builder
import java.io.IOException

class Gitmojis(val gitmojis: List<Gitmoji>) {
class Gitmoji(val emoji: String, val code: String, val description: String, val name: String)
object Gitmojis {
val gitmojis = ArrayList<GitmojiData>()

companion object {
fun defaultDisplayType(): String {
return if (SystemInfo.isWindows) "icon" else "emoji"
}
init {
loadGitmojiFromHTTP()
}

private fun loadGitmojiFromHTTP() {
val client = OkHttpClient().newBuilder().addInterceptor(SafeGuardInterceptor()).build()
val request: Request = Builder()
.url("https://gitmoji.dev/api/gitmojis")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
loadDefaultGitmoji()
}

fun insertAt(target: String, position: Int, insert: String): String {
val targetLen = target.length
require(!(position < 0 || position > targetLen)) { "position=$position" }
if (insert.isEmpty()) {
return target
override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) loadDefaultGitmoji()
else {
loadGitmoji(response.body!!.string())
}
}
}
if (position == 0) {
return insert + target
} else if (position == targetLen) {
return target + insert
})
}

private fun loadDefaultGitmoji() {
javaClass.getResourceAsStream("/gitmojis.json").use { inputStream ->
if (inputStream != null) {
val text = inputStream.bufferedReader().readText()
loadGitmoji(text)
}
val insertLen = insert.length
val buffer = CharArray(targetLen + insertLen)
target.toCharArray(buffer, 0, 0, position)
insert.toCharArray(buffer, position, 0, insertLen)
target.toCharArray(buffer, position + insertLen, position, targetLen)
return String(buffer)
}
}
}

private fun loadGitmoji(text: String) {
Gson().fromJson(text, JsonGitmojis::class.java).also {
it.gitmojis.forEach { gitmoji ->
gitmojis.add(GitmojiData(gitmoji.code, gitmoji.emoji, gitmoji.description, gitmoji.name))
}
}
GitmojiLocale.loadTranslations()
}

}
5 changes: 5 additions & 0 deletions src/main/kotlin/com/github/patou/gitmoji/JsonGitmojis.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.github.patou.gitmoji

class JsonGitmojis(val gitmojis: List<JsonGitmoji>) {
class JsonGitmoji(val emoji: String, val code: String, val description: String, val name: String)
}
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
</actions>

<extensions defaultExtensionNs="com.intellij">

<projectConfigurable instance="com.github.patou.gitmoji.GitMojiConfig" groupId="other" key="projectName" bundle="messages.GitmojiBundle"
id="com.github.patou.gitmoji.config"/>
<vcsLogCustomColumn implementation="com.github.patou.gitmoji.GitmojiCustomColumn" />
</extensions>
</idea-plugin>
Loading