Skip to content
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
4 changes: 4 additions & 0 deletions sdk/compose/icons/api/icons.api
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public final class io/github/composegears/valkyrie/sdk/compose/icons/colored/Luc
public static final fun getLucideLogo (Lio/github/composegears/valkyrie/sdk/compose/icons/ValkyrieIcons$Colored;)Landroidx/compose/ui/graphics/vector/ImageVector;
}

public final class io/github/composegears/valkyrie/sdk/compose/icons/colored/OcticonsLogoKt {
public static final fun getOcticonsLogo (Lio/github/composegears/valkyrie/sdk/compose/icons/ValkyrieIcons$Colored;)Landroidx/compose/ui/graphics/vector/ImageVector;
}

public final class io/github/composegears/valkyrie/sdk/compose/icons/colored/PluginIconKt {
public static final fun getPluginIcon (Lio/github/composegears/valkyrie/sdk/compose/icons/ValkyrieIcons$Colored;)Landroidx/compose/ui/graphics/vector/ImageVector;
}
Expand Down
2 changes: 2 additions & 0 deletions sdk/compose/icons/api/icons.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ final val io.github.composegears.valkyrie.sdk.compose.icons.colored/IoniconsLogo
final fun (io.github.composegears.valkyrie.sdk.compose.icons/ValkyrieIcons.Colored).<get-IoniconsLogo>(): androidx.compose.ui.graphics.vector/ImageVector // io.github.composegears.valkyrie.sdk.compose.icons.colored/IoniconsLogo.<get-IoniconsLogo>|<get-IoniconsLogo>@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored(){}[0]
final val io.github.composegears.valkyrie.sdk.compose.icons.colored/LucideLogo // io.github.composegears.valkyrie.sdk.compose.icons.colored/LucideLogo|@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored{}LucideLogo[0]
final fun (io.github.composegears.valkyrie.sdk.compose.icons/ValkyrieIcons.Colored).<get-LucideLogo>(): androidx.compose.ui.graphics.vector/ImageVector // io.github.composegears.valkyrie.sdk.compose.icons.colored/LucideLogo.<get-LucideLogo>|<get-LucideLogo>@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored(){}[0]
final val io.github.composegears.valkyrie.sdk.compose.icons.colored/OcticonsLogo // io.github.composegears.valkyrie.sdk.compose.icons.colored/OcticonsLogo|@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored{}OcticonsLogo[0]
final fun (io.github.composegears.valkyrie.sdk.compose.icons/ValkyrieIcons.Colored).<get-OcticonsLogo>(): androidx.compose.ui.graphics.vector/ImageVector // io.github.composegears.valkyrie.sdk.compose.icons.colored/OcticonsLogo.<get-OcticonsLogo>|<get-OcticonsLogo>@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored(){}[0]
final val io.github.composegears.valkyrie.sdk.compose.icons.colored/PluginIcon // io.github.composegears.valkyrie.sdk.compose.icons.colored/PluginIcon|@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored{}PluginIcon[0]
final fun (io.github.composegears.valkyrie.sdk.compose.icons/ValkyrieIcons.Colored).<get-PluginIcon>(): androidx.compose.ui.graphics.vector/ImageVector // io.github.composegears.valkyrie.sdk.compose.icons.colored/PluginIcon.<get-PluginIcon>|<get-PluginIcon>@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored(){}[0]
final val io.github.composegears.valkyrie.sdk.compose.icons.colored/RemixLogo // io.github.composegears.valkyrie.sdk.compose.icons.colored/RemixLogo|@io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons.Colored{}RemixLogo[0]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.github.composegears.valkyrie.sdk.compose.icons.colored

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.addPathNodes
import androidx.compose.ui.unit.dp
import io.github.composegears.valkyrie.sdk.compose.icons.ValkyrieIcons

@Suppress("UnusedReceiverParameter")
val ValkyrieIcons.Colored.OcticonsLogo: ImageVector
get() {
if (_OcticonsLogo != null) {
return _OcticonsLogo!!
}
_OcticonsLogo = ImageVector.Builder(
name = "Colored.OcticonsLogo",
defaultWidth = 24.dp,
defaultHeight = 24.dp,
viewportWidth = 460f,
viewportHeight = 460f,
).apply {
addPath(
pathData = addPathNodes("M0,0h460v460h-460z"),
fill = SolidColor(Color(0xFF0969DA)),
)
addPath(
pathData = addPathNodes(
"M75.642,258.999 C75.643,220.011 75.695,181.523 75.562,143.035 C75.549,139.19 76.613,137.748 80.511,136.756 C100.974,131.551 121.318,125.875 141.718,120.418 C170.788,112.643 199.867,104.896 228.965,97.223 C230.487,96.821 232.311,96.894 233.845,97.305 C266.606,106.084 299.332,114.996 332.095,123.764 C349.285,128.364 366.535,132.734 383.752,137.232 C384.706,137.481 385.603,137.948 386.844,138.44 C386.844,140.048 386.844,141.698 386.844,143.348 C386.844,202.33 386.804,261.312 386.935,320.293 C386.944,324.182 385.816,325.518 382.015,326.491 C362.029,331.608 342.156,337.164 322.229,342.513 C292.505,350.491 262.772,358.435 233.025,366.329 C231.826,366.647 230.383,366.553 229.167,366.227 C203.777,359.429 178.414,352.535 153.025,345.733 C128.438,339.146 103.856,332.536 79.198,326.224 C75.778,325.348 75.609,323.674 75.616,320.981 C75.667,300.487 75.643,279.993 75.642,258.999 Z",
),
fill = SolidColor(Color(0xFFFAFAFA)),
)
addPath(
pathData = addPathNodes(
"M184.128,332.842 C155.736,325.32 127.748,317.873 99.748,310.474 C97.479,309.875 96.04,309.246 96.048,306.29 C96.164,261.463 96.138,216.636 96.158,171.808 C96.159,171.323 96.34,170.838 96.523,169.92 C99.298,170.486 102.073,170.896 104.761,171.623 C138.18,180.66 171.585,189.75 205,198.806 C209.016,199.895 213.032,201.022 217.108,201.837 C220.164,202.448 221.009,204.009 220.983,207.028 C220.845,223.025 220.918,239.024 220.918,255.021 C220.918,282.184 220.918,309.347 220.918,336.51 C220.918,338.327 220.918,340.144 220.918,342.834 C208.43,339.434 196.48,336.181 184.128,332.842 Z",
),
fill = SolidColor(Color(0xFF0969DA)),
)
addPath(
pathData = addPathNodes(
"M283.047,214 C283.047,223.448 283.047,232.396 283.047,242.075 C297.361,238.3 310.962,234.714 324.715,231.088 C324.715,216.297 324.973,201.978 324.581,187.677 C324.435,182.327 325.75,179.79 331.295,178.582 C342.801,176.077 354.134,172.77 366.188,169.623 C366.307,171.899 366.465,173.499 366.462,175.099 C366.386,218.405 366.243,261.71 366.295,305.015 C366.299,308.57 365.135,309.9 361.846,310.765 C326.932,319.945 292.055,329.263 257.17,338.551 C252.211,339.872 247.265,341.24 241.453,342.82 C241.453,340.712 241.453,339.14 241.453,337.568 C241.453,294.427 241.501,251.286 241.37,208.146 C241.358,204.403 242.199,202.487 246.083,201.523 C258.163,198.523 270.149,195.146 283.047,191.68 C283.047,199.358 283.047,206.429 283.047,214 Z",
),
fill = SolidColor(Color(0xFF0969DA)),
)
addPath(
pathData = addPathNodes(
"M203.532,149.449 C229.361,156.428 254.8,163.288 280.24,170.147 C280.245,170.453 280.25,170.76 280.255,171.066 C275.832,172.399 271.439,173.846 266.98,175.042 C255.901,178.015 244.807,180.934 233.679,183.714 C232.015,184.13 230.043,184.014 228.364,183.572 C199.907,176.089 171.474,168.51 143.033,160.963 C130.342,157.595 117.639,154.277 104.959,150.87 C103.213,150.401 101.57,149.547 100.009,147.759 C115.717,143.609 131.358,139.164 147.185,135.534 C150.73,134.721 154.988,136.531 158.816,137.526 C173.614,141.374 188.37,145.381 203.532,149.449 Z",
),
fill = SolidColor(Color(0xFF0969DA)),
)
addPath(
pathData = addPathNodes(
"M269.889,123.193 C300.967,131.456 331.647,139.623 362.328,147.791 C362.328,148.343 362.328,148.895 362.328,149.447 C358.505,150.572 354.687,151.713 350.856,152.811 C349.577,153.178 348.157,153.212 346.985,153.778 C326.594,163.617 307.466,155.039 288.086,149.847 C256.918,141.497 225.73,133.216 194.557,124.885 C193.626,124.636 192.759,124.153 191.035,123.435 C204.206,119.972 216.516,116.572 228.929,113.606 C231.507,112.99 234.567,113.606 237.238,114.299 C248.025,117.095 258.746,120.143 269.889,123.193 Z",
),
fill = SolidColor(Color(0xFF0969DA)),
)
}.build()

return _OcticonsLogo!!
}

@Suppress("ObjectPropertyName")
private var _OcticonsLogo: ImageVector? = null
1 change: 1 addition & 0 deletions tools/idea-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

- [Web Import] Add `css.gg` icons provider
- [Web Import] Add `Octicons` icons provider
- [Web Import] Add `Simple` icons provider
- [Web Import] Add `Hero` icons provider
- [Web Import] Add floating zoom control bar to the icon grid β€” allows changing the visual display size of icons (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ class PersistentSettings : SimplePersistentStateComponent<ValkyrieState>(Valkyri

// css.gg
var cssGgSize: Int by property(DEFAULT_SIZE)

// Octicons
var octiconsSize: Int by property(DEFAULT_SIZE)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class InMemorySettings(project: Project) {
simpleIconsSize = DEFAULT_SIZE
heroiconsSize = DEFAULT_SIZE
cssGgSize = DEFAULT_SIZE
octiconsSize = DEFAULT_SIZE
}

fun updateUIState(uiState: SavedState) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import io.github.composegears.valkyrie.ui.screen.webimport.standard.simpleicons.
import io.github.composegears.valkyrie.ui.screen.webimport.standard.tabler.TablerImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.cssgg.CssGgImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.heroicons.HeroiconsImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.OcticonsImportScreen

val WebImportFlow by navDestination {
Navigation(
Expand All @@ -38,6 +39,7 @@ val WebImportFlow by navDestination {
EvaImportScreen,
FeatherImportScreen,
HeroiconsImportScreen,
OcticonsImportScreen,
IoniconsImportScreen,
SimpleIconsImportScreen,
CssGgImportScreen,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import io.github.composegears.valkyrie.sdk.compose.icons.colored.GoogleMaterialL
import io.github.composegears.valkyrie.sdk.compose.icons.colored.HeroiconsLogo
import io.github.composegears.valkyrie.sdk.compose.icons.colored.IoniconsLogo
import io.github.composegears.valkyrie.sdk.compose.icons.colored.LucideLogo
import io.github.composegears.valkyrie.sdk.compose.icons.colored.OcticonsLogo
import io.github.composegears.valkyrie.sdk.compose.icons.colored.RemixLogo
import io.github.composegears.valkyrie.sdk.compose.icons.colored.SimpleLogo
import io.github.composegears.valkyrie.sdk.compose.icons.colored.TablerLogo
Expand All @@ -45,6 +46,7 @@ import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.GoogleM
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.Heroicons
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.Ionicons
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.Lucide
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.Octicons
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.Remix
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.SimpleIcons
import io.github.composegears.valkyrie.ui.screen.webimport.IconProviders.Tabler
Expand All @@ -61,6 +63,7 @@ import io.github.composegears.valkyrie.ui.screen.webimport.standard.simpleicons.
import io.github.composegears.valkyrie.ui.screen.webimport.standard.tabler.TablerImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.cssgg.CssGgImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.heroicons.HeroiconsImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.OcticonsImportScreen
import io.github.composegears.valkyrie.util.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.jetbrains.jewel.ui.component.VerticallyScrollableContainer
Expand All @@ -82,6 +85,7 @@ val WebImportSelectorScreen by navDestination {
Eva -> EvaImportScreen
Feather -> FeatherImportScreen
Heroicons -> HeroiconsImportScreen
Octicons -> OcticonsImportScreen
Ionicons -> IoniconsImportScreen
SimpleIcons -> SimpleIconsImportScreen
CssGg -> CssGgImportScreen
Expand Down Expand Up @@ -180,6 +184,11 @@ enum class IconProviders(
titleKey = "web.import.selector.lucide.title",
descriptionKey = "web.import.selector.lucide.description",
),
Octicons(
icon = ValkyrieIcons.Colored.OcticonsLogo,
titleKey = "web.import.selector.octicons.title",
descriptionKey = "web.import.selector.octicons.description",
),
Remix(
icon = ValkyrieIcons.Colored.RemixLogo,
titleKey = "web.import.selector.remix.title",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons

import androidx.compose.runtime.Composable
import com.composegears.leviathan.compose.inject
import com.composegears.tiamat.compose.TiamatPreview
import com.composegears.tiamat.compose.back
import com.composegears.tiamat.compose.navController
import com.composegears.tiamat.compose.navDestination
import com.composegears.tiamat.compose.navigate
import io.github.composegears.valkyrie.jewel.tooling.ProjectPreviewTheme
import io.github.composegears.valkyrie.ui.screen.mode.simple.conversion.SimpleConversionParamsSource.TextSource
import io.github.composegears.valkyrie.ui.screen.mode.simple.conversion.SimpleConversionScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.common.SvgImportScreen
import io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.di.OcticonsModule
import io.github.composegears.valkyrie.util.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview

val OcticonsImportScreen by navDestination {
val navController = navController()
SvgImportScreen(
title = stringResource("web.import.title.octicons"),
provider = inject(OcticonsModule.octiconsUseCase),
onBack = navController::back,
onIconDownload = {
navController.parent?.navigate(
dest = SimpleConversionScreen,
navArgs = TextSource(
name = it.name,
text = it.svgContent,
),
)
},
)
}

@Preview
@Composable
private fun OcticonsImportScreenPreview() = ProjectPreviewTheme {
TiamatPreview(OcticonsImportScreen)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.data

data class OcticonsIconMetadata(
val name: String,
val size: String,
val width: Int,
val path: String,
val tags: List<String>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.data

import kotlinx.serialization.json.Json
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

class OcticonsMetadataParser(
private val json: Json = Json,
) {
fun parse(text: String): List<OcticonsIconMetadata> {
val root = json.parseToJsonElement(text).jsonObject
return root.flatMap { (name, iconElement) ->
val iconObject = iconElement.jsonObject
val keywords = iconObject["keywords"]
?.jsonArray
?.mapNotNull { it.jsonPrimitive.contentOrNull }
.orEmpty()
val tags = (name.split('-') + keywords).distinct()

iconObject["heights"]
?.jsonObject
?.entries
.orEmpty()
.sortedBy { it.key.toIntOrNull() ?: Int.MAX_VALUE }
.mapNotNull { (size, heightElement) ->
val width = heightElement.jsonObject["width"]?.jsonPrimitive?.content?.toIntOrNull()
?: return@mapNotNull null
OcticonsIconMetadata(
name = name,
size = size,
width = width,
path = "$name-$size.svg",
tags = tags,
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.data

import io.github.composegears.valkyrie.util.coroutines.suspendLazy
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText
import io.ktor.http.isSuccess
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive

class OcticonsRepository(
private val httpClient: HttpClient,
private val json: Json,
private val metadataParser: OcticonsMetadataParser,
) {
private val latestVersion = suspendLazy {
withContext(Dispatchers.IO) {
json.parseToJsonElement(httpClient.get(PACKAGE_JSON_URL).bodyAsText())
.jsonObject["version"]
?.jsonPrimitive
?.content
?: error("Failed to resolve Octicons package version")
}
}

private val metadata = suspendLazy {
withContext(Dispatchers.IO) {
metadataParser.parse(httpClient.get(resolveMetadataUrl(latestVersion())).bodyAsText())
}
}

suspend fun loadMetadata(): List<OcticonsIconMetadata> = metadata()

suspend fun downloadSvg(path: String): String = withContext(Dispatchers.IO) {
val response = httpClient.get(resolveOcticonsSvgUrl(path, version = latestVersion()))
if (!response.status.isSuccess()) {
error("Failed to download css.gg SVG: HTTP ${response.status.value}")
}
response.bodyAsText()
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

private companion object {
private const val PACKAGE_JSON_URL = "https://cdn.jsdelivr.net/npm/@primer/octicons@latest/package.json"

private fun resolveMetadataUrl(version: String): String {
return "https://cdn.jsdelivr.net/npm/@primer/octicons@$version/build/data.json"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.data

fun resolveOcticonsSvgUrl(path: String, version: String): String {
return "https://cdn.jsdelivr.net/npm/@primer/octicons@$version/build/svg/${path.trimStart('/')}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.di

import com.composegears.leviathan.Leviathan
import io.github.composegears.valkyrie.ui.di.coreModule
import io.github.composegears.valkyrie.ui.screen.webimport.common.di.NetworkModule
import io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.data.OcticonsMetadataParser
import io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.data.OcticonsRepository
import io.github.composegears.valkyrie.ui.screen.webimport.svg.octicons.domain.OcticonsUseCase

object OcticonsModule : Leviathan() {
private val network = NetworkModule
private val core = coreModule()

private val octiconsMetadataParser by factoryOf { OcticonsMetadataParser(json = inject(network.json)) }

private val octiconsRepository by instanceOf {
OcticonsRepository(
httpClient = inject(network.httpClient),
json = inject(network.json),
metadataParser = inject(octiconsMetadataParser),
)
}

val octiconsUseCase by instanceOf {
OcticonsUseCase(
repository = inject(octiconsRepository),
inMemorySettings = inject(core.inMemorySettings),
)
}
}
Loading
Loading