Skip to content

Commit

Permalink
Merge pull request #1 from bluelhf/main
Browse files Browse the repository at this point in the history
Several fixes and QOL changes
  • Loading branch information
developerfromjokela authored Aug 4, 2022
2 parents 2a60fa0 + b22e2bd commit db293c4
Show file tree
Hide file tree
Showing 26 changed files with 519 additions and 318 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.gradle
.idea
**/.idea
.qodana
build
16 changes: 13 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<!-- Keep a Changelog guide -> https://keepachangelog.com -->

# testaustime-intellij Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.2.0] - 2022-08-04

### Added
- Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)
- Input verification on the settings page.
- Project-level Testaustime notifications.
### Changed
- Improved some English messages.
- Fixed tracking when multiple projects are open.
- Split notifications into Testaustime Information and Testaustime Warnings.
44 changes: 18 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,29 @@
# Testaustime IntelliJ Plugin

![Build](https://github.com/developerfromjokela/testaustime-intellij/workflows/Build/badge.svg)
[![Version](https://img.shields.io/jetbrains/plugin/v/PLUGIN_ID.svg)](https://plugins.jetbrains.com/plugin/PLUGIN_ID)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/PLUGIN_ID.svg)](https://plugins.jetbrains.com/plugin/PLUGIN_ID)

## Template ToDo list
- [x] Create a new [IntelliJ Platform Plugin Template][template] project.
- [ ] Get familiar with the [template documentation][template].
- [ ] Verify the [pluginGroup](/gradle.properties), [plugin ID](/src/main/resources/META-INF/plugin.xml) and [sources package](/src/main/kotlin).
- [ ] Review the [Legal Agreements](https://plugins.jetbrains.com/docs/marketplace/legal-agreements.html).
- [ ] [Publish a plugin manually](https://plugins.jetbrains.com/docs/intellij/publishing-plugin.html?from=IJPluginTemplate) for the first time.
- [ ] Set the Plugin ID in the above README badges.
- [ ] Set the [Deployment Token](https://plugins.jetbrains.com/docs/marketplace/plugin-upload.html).
- [ ] Click the <kbd>Watch</kbd> button on the top of the [IntelliJ Platform Plugin Template][template] to be notified about releases containing new features and fixes.
[![Version](https://img.shields.io/jetbrains/plugin/v/19408.svg)](https://plugins.jetbrains.com/plugin/19408)
[![Downloads](https://img.shields.io/jetbrains/plugin/d/19408.svg)](https://plugins.jetbrains.com/plugin/19408)
---

<!-- Plugin description -->
Testaustime is the ultimate tool for tracking time of your coding sessions. Show the world how dedicated you are to your projects, now available for IntelliJ IDEs!
<!-- Plugin description end -->

## Installation
> **Note**
> Here from [testaustime.fi](https://testaustime.fi)? You can skip steps 2 and 5!
- Using IDE built-in plugin system:
1. Install the Testaustime IntelliJ Plugin
- Using the IDE's built-in plugin system
- <kbd>Settings</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd>Search for "Testaustime"</kbd> > <kbd>Install Plugin</kbd>

<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>Marketplace</kbd> > <kbd>Search for "Testaustime"</kbd> >
<kbd>Install Plugin</kbd>

- Manually:

Download the [latest release](https://github.com/developerfromjokela/testaustime-intellij/releases/latest) and install it manually using
<kbd>Settings/Preferences</kbd> > <kbd>Plugins</kbd> > <kbd>⚙️</kbd> > <kbd>Install plugin from disk...</kbd>


---
Plugin based on the [IntelliJ Platform Plugin Template][template].

[template]: https://github.com/JetBrains/intellij-platform-plugin-template
- Manually:
1. Download the [latest release](https://github.com/developerfromjokela/testaustime-intellij/releases/latest) and install it manually using
2. <kbd>Settings</kbd> > <kbd>Plugins</kbd> > <kbd>⚙️</kbd> > <kbd>Install plugin from disk...</kbd>

2. <sup>(Optional)</sup> Set your Testaustime API endpoint
- <kbd>Settings</kbd> > <kbd>Tools</kbd> > <kbd>Testaustime Settings</kbd> > <kbd>Testaustime API base URL</kbd>
3. Set your Testaustime API token
- <kbd>Settings</kbd> > <kbd>Tools</kbd> > <kbd>Testaustime Settings</kbd> > <kbd>Testaustime Authentication token</kbd>
4. Start coding!
5. View your stats on your favourite Testaustime front-end!
6 changes: 2 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ plugins {
// Java support
id("java")
// Kotlin support
id("org.jetbrains.kotlin.jvm") version "1.6.10"
id("org.jetbrains.kotlin.jvm") version "1.7.10"
// Gradle IntelliJ Plugin
id("org.jetbrains.intellij") version "1.4.0"
id("org.jetbrains.intellij") version "1.7.0"
// Gradle Changelog Plugin
id("org.jetbrains.changelog") version "1.3.1"
// Gradle Qodana Plugin
Expand All @@ -20,8 +20,6 @@ group = properties("pluginGroup")
version = properties("pluginVersion")

dependencies {
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.9.0")
implementation("com.google.code.gson:gson:2.9.0")
}

Expand Down
14 changes: 7 additions & 7 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,27 @@
pluginGroup = fi.testaustime.plugin_intellij
pluginName = testaustime-intellij
# SemVer format -> https://semver.org
pluginVersion = 0.1.2
pluginVersion = 0.2.0

# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 211
pluginUntilBuild = 216.*
pluginSinceBuild = 212.4746.92
pluginUntilBuild = 282.*


# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IC
platformVersion = 2021.1.3
platformVersion = 2022.2

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins = org.jetbrains.kotlin

# Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3
javaVersion = 11
# Java language level used to compile sources and to generate the files for - Java 17 is required since 2022.2
javaVersion = 17

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 7.4
gradleVersion = 7.5

# Opt-out flag for bundling Kotlin standard library.
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import org.jetbrains.annotations.NonNls
import org.jetbrains.annotations.PropertyKey

@NonNls
private const val BUNDLE = "messages.MyBundle"
private const val BUNDLE = "messages.TestaustimeBundle"

object TestausTimeBundle : DynamicBundle(BUNDLE) {
object TestaustimeBundle : DynamicBundle(BUNDLE) {

@Suppress("SpreadOperator")
@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
package fi.testaustime.plugin_intellij.configuration

import com.intellij.openapi.components.service
import com.intellij.openapi.options.Configurable
import fi.testaustime.plugin_intellij.TestaustimeBundle
import fi.testaustime.plugin_intellij.services.TestaustimeApplicationService
import org.jetbrains.annotations.Nullable
import javax.swing.JComponent



class IntellijSettingConfigurable : Configurable {
private var settingsComponent: IntellijSettingsComponent? = null


fun preferredFocusedComponent(): JComponent? {
return settingsComponent?.preferredFocusedComponent;
}
class ConfigurableSettings : Configurable {
private var settingsComponent: SettingsComponent? = null

@Nullable
override fun createComponent(): JComponent? {
settingsComponent = IntellijSettingsComponent()
settingsComponent = SettingsComponent()
return settingsComponent?.panel
}

override fun isModified(): Boolean {
val settings: TestausTimeSettingsState = TestausTimeSettingsState.instance
val settings: SettingsState = SettingsState.instance
var modified: Boolean = !settingsComponent?.baseUrl.equals(settings.apiBaseUrl)
modified = modified or (!settingsComponent?.authToken.equals(settings.authToken))
modified = modified and (settingsComponent?.validate() ?: false)
return modified
}


override fun apply() {
val settings: TestausTimeSettingsState = TestausTimeSettingsState.instance
val settings: SettingsState = SettingsState.instance
settings.apiBaseUrl = settingsComponent?.baseUrl ?: "https://api.testaustime.fi"
settings.authToken = settingsComponent?.authToken ?: ""

// Validate token immediately
service<TestaustimeApplicationService>().pingNow();
}

override fun reset() {
val settings: TestausTimeSettingsState = TestausTimeSettingsState.instance
val settings: SettingsState = SettingsState.instance
settingsComponent?.baseUrl = settings.apiBaseUrl
settingsComponent?.authToken = settings.authToken
}
Expand All @@ -45,6 +47,6 @@ class IntellijSettingConfigurable : Configurable {
}

override fun getDisplayName(): String {
return "Testaustime Settings"
return TestaustimeBundle.message("name");
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package fi.testaustime.plugin_intellij.configuration

import com.intellij.openapi.ui.ComponentValidator
import com.intellij.openapi.ui.ValidationInfo
import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBTextField
import com.intellij.util.ui.FormBuilder
import fi.testaustime.plugin_intellij.TestaustimeBundle.message
import fi.testaustime.plugin_intellij.network.TestaustimeAPIClient
import org.jetbrains.annotations.NotNull
import java.net.MalformedURLException
import java.net.URL
import java.util.function.Supplier
import javax.swing.InputVerifier
import javax.swing.JComponent
import javax.swing.JPanel


class SettingsComponent {
fun validate(): Boolean {
var valid = baseUrlText.inputVerifier?.verify(baseUrlText) ?: false;
valid = valid and (authTokenText.inputVerifier?.verify(authTokenText) ?: false);
return valid
}

val panel: JPanel
private val baseUrlText = JBTextField()
private val authTokenText = JBTextField()

init {
panel = FormBuilder.createFormBuilder()
.addLabeledComponent(JBLabel(message("settings.apiBaseURL") + ": "), baseUrlText, 1, false)
.addLabeledComponent(JBLabel(message("settings.apiToken") + ": "), authTokenText, 1, false)
.addComponentFillVertically(JPanel(), 0)
.panel

run {
val validator = ComponentValidator { }.withValidator(Supplier {
if (baseUrlText.text.endsWith("/")) {
return@Supplier ValidationInfo(message("settings.apiBaseURL.noSlash"), baseUrlText)
} else {
try {
URL(baseUrlText.text)
} catch (ex: MalformedURLException) {
return@Supplier ValidationInfo(message("settings.apiBaseURL.mustBeURL"), baseUrlText)
}
}

return@Supplier ValidationInfo("").withOKEnabled();
}).installOn(baseUrlText)

baseUrlText.inputVerifier = object : InputVerifier() {
override fun verify(input: JComponent?): Boolean {
validator.revalidate()
return validator.validationInfo?.okEnabled ?: true;
}
}
}


run {
val validator = ComponentValidator { }.withValidator(Supplier {
if (authTokenText.text.isEmpty()) {
return@Supplier ValidationInfo(message("settings.apiToken.needToken"), authTokenText).asWarning();
}

if (!authTokenText.text.chars().allMatch(Character::isLetterOrDigit)) {
return@Supplier ValidationInfo(message("settings.apiToken.mustBeAlphanumeric"), authTokenText);
}

if (authTokenText.text.length != 32) {
return@Supplier ValidationInfo(message("settings.apiToken.invalidLength", authTokenText.text.length),
authTokenText);
}

if (!TestaustimeAPIClient.verifyToken(baseUrlText.text, authTokenText.text)) {
return@Supplier ValidationInfo(message("settings.apiToken.invalid", baseUrl ?: "The API"), authTokenText);
}

return@Supplier ValidationInfo("").withOKEnabled();
}).installOn(authTokenText)

authTokenText.inputVerifier = object : InputVerifier() {
override fun verify(input: JComponent?): Boolean {
validator.revalidate()
validator.validationInfo?.let {
return it.okEnabled or it.warning;
}
return false;
}
}
}
}

val preferredFocusedComponent: JComponent
get() = baseUrlText

@get:NotNull
var baseUrl: String?
get() = baseUrlText.text
set(newText) {
baseUrlText.text = newText
}

@get:NotNull
var authToken: String?
get() = authTokenText.text
set(newText) {
authTokenText.text = newText
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ import org.jetbrains.annotations.Nullable


@State(name = "fi.testaustime.plugin_intellij.configuration.TestausTimeSettingsState", storages = [Storage("TestausTimePlugin.xml")])
class TestausTimeSettingsState : PersistentStateComponent<TestausTimeSettingsState> {
class SettingsState : PersistentStateComponent<SettingsState> {
var apiBaseUrl = "https://api.testaustime.fi"
var authToken = ""

@Nullable
override fun getState(): TestausTimeSettingsState {
override fun getState(): SettingsState {
return this
}

override fun loadState(@NotNull state: TestausTimeSettingsState) {
override fun loadState(@NotNull state: SettingsState) {
XmlSerializerUtil.copyBean(state, this)
}

companion object {
val instance: TestausTimeSettingsState
get() = ApplicationManager.getApplication().getService(TestausTimeSettingsState::class.java)
val instance: SettingsState
get() = ApplicationManager.getApplication().getService(SettingsState::class.java)
}
}
Loading

0 comments on commit db293c4

Please sign in to comment.