Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

impl: ability to application name as main page title#220

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
fioan89 wants to merge8 commits intomain
base:main
Choose a base branch
Loading
fromimpl-option-to-display-app-name
Open
Show file tree
Hide file tree
Changes fromall 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
4 changes: 4 additions & 0 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,6 +2,10 @@

## Unreleased

### Added

- application name can now be displayed as the main title page instead of the URL

## 0.7.2 - 2025-11-03

### Changed
Expand Down
26 changes: 21 additions & 5 deletionssrc/main/kotlin/com/coder/toolbox/CoderRemoteProvider.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,16 +57,25 @@ class CoderRemoteProvider(

private val triggerSshConfig = Channel<Boolean>(Channel.CONFLATED)
private val triggerProviderVisible = Channel<Boolean>(Channel.CONFLATED)
private val settingsPage: CoderSettingsPage = CoderSettingsPage(context, triggerSshConfig)
private val dialogUi = DialogUi(context)

// The REST client, if we are signed in
private var client: CoderRestClient? = null

// On the first load, automatically log in if we can.
private var firstRun = true

private val isInitialized: MutableStateFlow<Boolean> = MutableStateFlow(false)
private val coderHeaderPage = NewEnvironmentPage(context.i18n.pnotr(context.deploymentUrl.toString()))
private val settingsPage: CoderSettingsPage = CoderSettingsPage(context, triggerSshConfig) {
client?.let { restClient ->
if (context.settingsStore.useAppNameAsTitle) {
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.appName))
} else {
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.url.toString()))
}
}
}
private val visibilityState = MutableStateFlow(
ProviderVisibilityState(
applicationVisible = false,
Expand DownExpand Up@@ -227,7 +236,7 @@ class CoderRemoteProvider(
val url = context.settingsStore.workspaceCreateUrl ?: client?.url?.withPath("/templates").toString()
context.desktop.browse(
url
.replace("\$workspaceOwner", client?.me()?.username ?: "")
.replace("\$workspaceOwner", client?.me?.username ?: "")
) {
context.ui.showErrorInfoPopup(it)
}
Expand DownExpand Up@@ -333,8 +342,11 @@ class CoderRemoteProvider(
}
context.logger.info("Starting initialization with the new settings")
this@CoderRemoteProvider.client = restClient
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.url.toString()))

if (context.settingsStore.useAppNameAsTitle) {
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.appName))
} else {
coderHeaderPage.setTitle(context.i18n.pnotr(restClient.url.toString()))
}
environments.showLoadingMessage()
pollJob = poll(restClient, cli)
context.logger.info("Workspace poll job with name ${pollJob.toString()} was created while handling URI $uri")
Expand DownExpand Up@@ -421,7 +433,11 @@ class CoderRemoteProvider(
context.logger.info("Cancelled workspace poll job ${pollJob.toString()} in order to start a new one")
}
environments.showLoadingMessage()
coderHeaderPage.setTitle(context.i18n.pnotr(client.url.toString()))
if (context.settingsStore.useAppNameAsTitle) {
coderHeaderPage.setTitle(context.i18n.pnotr(client.appName))
} else {
coderHeaderPage.setTitle(context.i18n.pnotr(client.url.toString()))
}
context.logger.info("Displaying ${client.url} in the UI")
pollJob = poll(client, cli)
context.logger.info("Workspace poll job with name ${pollJob.toString()} was created")
Expand Down
24 changes: 23 additions & 1 deletionsrc/main/kotlin/com/coder/toolbox/sdk/CoderRestClient.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,6 +10,7 @@ import com.coder.toolbox.sdk.ex.APIResponseException
import com.coder.toolbox.sdk.interceptors.Interceptors
import com.coder.toolbox.sdk.v2.CoderV2RestFacade
import com.coder.toolbox.sdk.v2.models.ApiErrorResponse
import com.coder.toolbox.sdk.v2.models.Appearance
import com.coder.toolbox.sdk.v2.models.BuildInfo
import com.coder.toolbox.sdk.v2.models.CreateWorkspaceBuildRequest
import com.coder.toolbox.sdk.v2.models.Template
Expand DownExpand Up@@ -45,6 +46,7 @@ open class CoderRestClient(

lateinit var me: User
lateinit var buildVersion: String
lateinit var appName: String

init {
setupSession()
Expand DownExpand Up@@ -94,14 +96,15 @@ open class CoderRestClient(
suspend fun initializeSession(): User {
me = me()
buildVersion = buildInfo().version
appName = appearance().applicationName
return me
}

/**
* Retrieve the current user.
* @throws [APIResponseException].
*/
suspend fun me(): User {
internalsuspend fun me(): User {
val userResponse = retroRestClient.me()
if (!userResponse.isSuccessful) {
throw APIResponseException(
Expand All@@ -117,6 +120,25 @@ open class CoderRestClient(
}
}

/**
* Retrieves the visual dashboard configuration.
*/
internal suspend fun appearance(): Appearance {
val appearanceResponse = retroRestClient.appearance()
if (!appearanceResponse.isSuccessful) {
throw APIResponseException(
"initializeSession",
url,
appearanceResponse.code(),
appearanceResponse.parseErrorBody(moshi)
)
}

return requireNotNull(appearanceResponse.body()) {
"Successful response returned null body or visual dashboard configuration"
}
}

/**
* Retrieves the available workspaces created by the user.
* @throws [APIResponseException].
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
package com.coder.toolbox.sdk.v2

import com.coder.toolbox.sdk.v2.models.Appearance
import com.coder.toolbox.sdk.v2.models.BuildInfo
import com.coder.toolbox.sdk.v2.models.CreateWorkspaceBuildRequest
import com.coder.toolbox.sdk.v2.models.Template
Expand All@@ -23,6 +24,12 @@ interface CoderV2RestFacade {
@GET("api/v2/users/me")
suspend fun me(): Response<User>

/**
* Returns the configuration of the visual dashboard.
*/
@GET("api/v2/appearance")
suspend fun appearance(): Response<Appearance>

/**
* Retrieves all workspaces the authenticated user has access to.
*/
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
package com.coder.toolbox.sdk.v2.models

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class Appearance(
@property:Json(name = "application_name") val applicationName: String
)
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,6 +19,12 @@ interface ReadOnlyCoderSettings {
*/
val defaultURL: String

/**
* Whether to display the application name instead of the URL
* in the main screen. Defaults to URL
*/
val useAppNameAsTitle: Boolean

/**
* Used to download the Coder CLI which is necessary to proxy SSH
* connections. The If-None-Match header will be set to the SHA1 of the CLI
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -38,6 +38,7 @@ class CoderSettingsStore(
// Properties implementation
override val lastDeploymentURL: String? get() = store[LAST_USED_URL]
override val defaultURL: String get() = store[DEFAULT_URL] ?: "https://dev.coder.com"
override val useAppNameAsTitle: Boolean get() = store[APP_NAME_AS_TITLE]?.toBooleanStrictOrNull() ?: false
override val binarySource: String? get() = store[BINARY_SOURCE]
override val binaryDirectory: String? get() = store[BINARY_DIRECTORY]
override val disableSignatureVerification: Boolean
Expand DownExpand Up@@ -165,6 +166,10 @@ class CoderSettingsStore(
store[LAST_USED_URL] = url.toString()
}

fun updateUseAppNameAsTitle(appNameAsTitle: Boolean) {
store[APP_NAME_AS_TITLE] = appNameAsTitle.toString()
}

fun updateBinarySource(source: String) {
store[BINARY_SOURCE] = source
}
Expand Down
2 changes: 2 additions & 0 deletionssrc/main/kotlin/com/coder/toolbox/store/StoreKeys.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,8 @@ internal const val LAST_USED_URL = "lastDeploymentURL"

internal const val DEFAULT_URL = "defaultURL"

internal const val APP_NAME_AS_TITLE = "useAppNameAsTitle"

internal const val BINARY_SOURCE = "binarySource"

internal const val BINARY_DIRECTORY = "binaryDirectory"
Expand Down
14 changes: 13 additions & 1 deletionsrc/main/kotlin/com/coder/toolbox/views/CoderSettingsPage.kt
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,11 @@ import kotlinx.coroutines.launch
* TODO@JB: There is no scroll, and our settings do not fit. As a consequence,
* I have not been able to test this page.
*/
class CoderSettingsPage(private val context: CoderToolboxContext, triggerSshConfig: Channel<Boolean>) :
class CoderSettingsPage(
private val context: CoderToolboxContext,
triggerSshConfig: Channel<Boolean>,
private val onSettingsClosed: () -> Unit
) :
CoderPage(MutableStateFlow(context.i18n.ptrl("Coder Settings")), false) {
private val settings = context.settingsStore.readOnly()

Expand All@@ -41,6 +45,8 @@ class CoderSettingsPage(private val context: CoderToolboxContext, triggerSshConf
TextField(context.i18n.ptrl("Data directory"), settings.dataDirectory ?: "", TextType.General)
private val enableDownloadsField =
CheckboxField(settings.enableDownloads, context.i18n.ptrl("Enable downloads"))
private val useAppNameField =
CheckboxField(settings.useAppNameAsTitle, context.i18n.ptrl("Use app name as main page title instead of URL"))

private val disableSignatureVerificationField = CheckboxField(
settings.disableSignatureVerification,
Expand DownExpand Up@@ -95,6 +101,7 @@ class CoderSettingsPage(private val context: CoderToolboxContext, triggerSshConf
listOf(
binarySourceField,
enableDownloadsField,
useAppNameField,
binaryDirectoryField,
enableBinaryDirectoryFallbackField,
disableSignatureVerificationField,
Expand All@@ -121,6 +128,7 @@ class CoderSettingsPage(private val context: CoderToolboxContext, triggerSshConf
context.settingsStore.updateBinaryDirectory(binaryDirectoryField.contentState.value)
context.settingsStore.updateDataDirectory(dataDirectoryField.contentState.value)
context.settingsStore.updateEnableDownloads(enableDownloadsField.checkedState.value)
context.settingsStore.updateUseAppNameAsTitle(useAppNameField.checkedState.value)
context.settingsStore.updateDisableSignatureVerification(disableSignatureVerificationField.checkedState.value)
context.settingsStore.updateSignatureFallbackStrategy(signatureFallbackStrategyField.checkedState.value)
context.settingsStore.updateHttpClientLogLevel(httpLoggingField.selectedValueState.value)
Expand DownExpand Up@@ -164,6 +172,9 @@ class CoderSettingsPage(private val context: CoderToolboxContext, triggerSshConf
enableDownloadsField.checkedState.update {
settings.enableDownloads
}
useAppNameField.checkedState.update {
settings.useAppNameAsTitle
}
signatureFallbackStrategyField.checkedState.update {
settings.fallbackOnCoderForSignatures.isAllowed()
}
Expand DownExpand Up@@ -225,5 +236,6 @@ class CoderSettingsPage(private val context: CoderToolboxContext, triggerSshConf

override fun afterHide() {
visibilityUpdateJob.cancel()
onSettingsClosed()
}
}
3 changes: 3 additions & 0 deletionssrc/main/resources/localization/defaultMessages.po
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -189,3 +189,6 @@ msgstr ""

msgid"Workspace name"
msgstr""

msgid"Use app name as main page title instead of URL"
msgstr""
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ internal class CoderProtocolHandlerTest {
private val protocolHandler = CoderProtocolHandler(
context,
DialogUi(context),
CoderSettingsPage(context, Channel(Channel.CONFLATED)),
CoderSettingsPage(context, Channel(Channel.CONFLATED), {}),
MutableStateFlow(ProviderVisibilityState(applicationVisible = true, providerVisible = true)),
MutableStateFlow(false)
)
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp