authorgravatar for maria@kuuro.netmaria <maria@kuuro.net> 2026-10-14 20:51:07+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-14 20:51:07+00:00
log348f217a853dd4a23d7fa4834dedb05f545c2075
treef5b725829b4c289fc96d9b4c613c66df3fca1d4b
parente47bfe4617f6fdca2c6513bd0afe0f6b8d24688a
signature Signed by PGP key B5690EEEBB952194

fix(web,mobile): muse code uses meta's official blue logo (#19562)


5 files changed, 102 insertions(+), 13 deletions(-)

apps/mobile/src/components/ProviderIcon.tsx+28-4
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1import { Image } from "expo-image";1import { Image } from "expo-image";
2import { Path, Svg } from "react-native-svg";2import { Defs, LinearGradient, Path, Stop, Svg } from "react-native-svg";
3import { View } from "react-native";3import { View } from "react-native";
4import { providerInstanceInitials } from "@t3tools/client-runtime/state/provider-instance-display";4import { providerInstanceInitials } from "@t3tools/client-runtime/state/provider-instance-display";
5import { useState } from "react";5import { useId, useState } from "react";
6import { resolveOfficialAcpRegistryIconUrl } from "@t3tools/contracts";6import { resolveOfficialAcpRegistryIconUrl } from "@t3tools/contracts";
7import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider";7import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider";
8import { AppText as Text } from "./AppText";8import { AppText as Text } from "./AppText";
...@@ -66,6 +66,7 @@ function AcpRegistryProviderIcon(props: {...@@ -66,6 +66,7 @@ function AcpRegistryProviderIcon(props: {
66export function ProviderIcon(props: ProviderIconProps) {66export function ProviderIcon(props: ProviderIconProps) {
67 const { themeAppearance } = useAppearancePreferences();67 const { themeAppearance } = useAppearancePreferences();
68 const isDarkMode = themeAppearance === "dark";68 const isDarkMode = themeAppearance === "dark";
69 const gradientId = useId();
69 const size = props.size ?? 16;70 const size = props.size ?? 16;
70 const mono = isDarkMode ? "#e5e5e5" : "#171717";71 const mono = isDarkMode ? "#e5e5e5" : "#171717";
7172
...@@ -99,12 +100,35 @@ export function ProviderIcon(props: ProviderIconProps) {...@@ -99,12 +100,35 @@ export function ProviderIcon(props: ProviderIconProps) {
99 isDarkMode ? fill.dark : fill.light;100 isDarkMode ? fill.dark : fill.light;
100 return (101 return (
101 <Svg width={size} height={size} viewBox={packageIcon.viewBox} fill="none">102 <Svg width={size} height={size} viewBox={packageIcon.viewBox} fill="none">
102 {packageIcon.paths.map((path) => (103 <Defs>
104 {packageIcon.paths.map((path, index) =>
105 path.gradient ? (
106 <LinearGradient
107 key={path.d}
108 id={`${gradientId}-${index}`}
109 x1={path.gradient.x1}
110 y1={path.gradient.y1}
111 x2={path.gradient.x2}
112 y2={path.gradient.y2}
113 gradientUnits="userSpaceOnUse"
114 >
115 {path.gradient.stops.map((stop) => (
116 <Stop key={stop.offset} offset={stop.offset} stopColor={stop.color} />
117 ))}
118 </LinearGradient>
119 ) : null,
120 )}
121 </Defs>
122 {packageIcon.paths.map((path, index) => (
103 <Path123 <Path
104 key={path.d}124 key={path.d}
105 d={path.d}125 d={path.d}
106 fillRule={path.fillRule}126 fillRule={path.fillRule}
107 fill={themeFill(path.fill ?? packageIcon.fill)}127 fill={
128 path.gradient
129 ? `url(#${gradientId}-${index})`
130 : themeFill(path.fill ?? packageIcon.fill)
131 }
108 />132 />
109 ))}133 ))}
110 </Svg>134 </Svg>
apps/web/src/components/chat/ChatComposer.tsx+2-1
...@@ -5649,7 +5649,8 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)...@@ -5649,7 +5649,8 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
5649 activeProviderIconClassName: cn(5649 activeProviderIconClassName: cn(
5650 composerProviderState.modelPickerIconClassName,5650 composerProviderState.modelPickerIconClassName,
5651 composerControlsCollapsed &&5651 composerControlsCollapsed &&
5652 "fill-muted-foreground/70! text-muted-foreground/70! [&_path]:fill-muted-foreground/70! [&_rect]:fill-muted-foreground/70! [&_[data-icon-detail]]:fill-transparent!",5652 // Package glyphs get opaque fills and one opacity, so overlapping paths don't band.
5653 "fill-muted-foreground/70! text-muted-foreground/70! [&_path]:fill-muted-foreground/70! [&_rect]:fill-muted-foreground/70! [&_[data-icon-detail]]:fill-transparent! [&[data-provider-package-icon]]:opacity-70 [&[data-provider-package-icon]_path:not([data-icon-detail])]:fill-muted-foreground!",
5653 ),5654 ),
5654 }5655 }
5655 : {})}5656 : {})}
apps/web/src/components/chat/ProviderPackageIcon.tsx+28-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1import type { CSSProperties, SVGProps } from "react";1import { useId, type CSSProperties, type SVGProps } from "react";
22
3import type { ProviderIcon } from "@t3tools/provider-core/client";3import type { ProviderIcon } from "@t3tools/provider-core/client";
44
...@@ -13,11 +13,14 @@ export function ProviderPackageIcon({...@@ -13,11 +13,14 @@ export function ProviderPackageIcon({
13 className,13 className,
14 ...props14 ...props
15}: { readonly icon: ProviderIcon } & SVGProps<SVGSVGElement>) {15}: { readonly icon: ProviderIcon } & SVGProps<SVGSVGElement>) {
16 const gradientId = useId();
16 return (17 return (
17 <svg18 <svg
18 {...props}19 {...props}
19 viewBox={icon.viewBox}20 viewBox={icon.viewBox}
20 fill="none"21 fill="none"
22 // Lets monochrome renderings dim the whole glyph once instead of each path.
23 data-provider-package-icon
21 className={cn("fill-(--icon-light) dark:fill-(--icon-dark)", className)}24 className={cn("fill-(--icon-light) dark:fill-(--icon-dark)", className)}
22 style={25 style={
23 {26 {
...@@ -26,11 +29,34 @@ export function ProviderPackageIcon({...@@ -26,11 +29,34 @@ export function ProviderPackageIcon({
26 } as CSSProperties29 } as CSSProperties
27 }30 }
28 >31 >
29 {icon.paths.map((path) => (32 {icon.paths.some((path) => path.gradient) ? (
33 <defs>
34 {icon.paths.map((path, index) =>
35 path.gradient ? (
36 <linearGradient
37 key={path.d}
38 id={`${gradientId}-${index}`}
39 x1={path.gradient.x1}
40 y1={path.gradient.y1}
41 x2={path.gradient.x2}
42 y2={path.gradient.y2}
43 gradientUnits="userSpaceOnUse"
44 >
45 {path.gradient.stops.map((stop) => (
46 <stop key={stop.offset} offset={stop.offset} stopColor={stop.color} />
47 ))}
48 </linearGradient>
49 ) : null,
50 )}
51 </defs>
52 ) : null}
53 {icon.paths.map((path, index) => (
30 <path54 <path
31 key={path.d}55 key={path.d}
32 d={path.d}56 d={path.d}
33 fillRule={path.fillRule}57 fillRule={path.fillRule}
58 // An attribute, so monochrome renderings can still override it from CSS.
59 fill={path.gradient ? `url(#${gradientId}-${index})` : undefined}
34 // Monochrome renderings (the collapsed composer) clear these detail paths.60 // Monochrome renderings (the collapsed composer) clear these detail paths.
35 data-icon-detail={path.fill ? true : undefined}61 data-icon-detail={path.fill ? true : undefined}
36 className={path.fill ? "fill-(--path-light) dark:fill-(--path-dark)" : undefined}62 className={path.fill ? "fill-(--path-light) dark:fill-(--path-dark)" : undefined}
packages/provider-core/src/client.ts+12-2
...@@ -33,8 +33,8 @@ export interface ProviderEnvironmentField {...@@ -33,8 +33,8 @@ export interface ProviderEnvironmentField {
3333
34/**34/**
35 * A provider glyph as plain data, so web and mobile can each draw it with35 * A provider glyph as plain data, so web and mobile can each draw it with
36 * their own SVG renderer. Colors are per theme; a path without a fill uses36 * their own SVG renderer. Colors are per theme; a path without a fill or
37 * the icon's `fill`.37 * gradient uses the icon's `fill`.
38 */38 */
39export interface ProviderIcon {39export interface ProviderIcon {
40 readonly viewBox: string;40 readonly viewBox: string;
...@@ -43,9 +43,19 @@ export interface ProviderIcon {...@@ -43,9 +43,19 @@ export interface ProviderIcon {
43 readonly d: string;43 readonly d: string;
44 readonly fillRule?: "evenodd" | "nonzero";44 readonly fillRule?: "evenodd" | "nonzero";
45 readonly fill?: { readonly light: string; readonly dark: string };45 readonly fill?: { readonly light: string; readonly dark: string };
46 /** A brand gradient, the same in both themes. Coordinates are in viewBox units. */
47 readonly gradient?: ProviderIconGradient;
46 }>;48 }>;
47}49}
4850
51export interface ProviderIconGradient {
52 readonly x1: number;
53 readonly y1: number;
54 readonly x2: number;
55 readonly y2: number;
56 readonly stops: ReadonlyArray<{ readonly offset: number; readonly color: string }>;
57}
58
49export interface ProviderClientDefinition {59export interface ProviderClientDefinition {
50 readonly driverKind: ProviderDriverKind;60 readonly driverKind: ProviderDriverKind;
51 readonly label: string;61 readonly label: string;
packages/provider-muse/src/client.ts+32-4
...@@ -14,13 +14,41 @@ export const museClient = defineProviderClient({...@@ -14,13 +14,41 @@ export const museClient = defineProviderClient({
14 label: "Muse Code",14 label: "Muse Code",
15 settingsSchema: MuseSettings,15 settingsSchema: MuseSettings,
16 badgeLabel: "Beta",16 badgeLabel: "Beta",
17 // Meta's symbol (https://commons.wikimedia.org/wiki/File:Meta_Platforms_Inc._logo_(cropped).svg).
17 icon: {18 icon: {
18 viewBox: "0 0 150.4828 100",19 viewBox: "0 0 287.56 191",
19 fill: { light: "#171717", dark: "#e5e5e5" },20 fill: { light: "#0081fb", dark: "#0081fb" },
20 paths: [21 paths: [
21 {22 {
22 d: "M107.9999847,0.0000013c-12.3391113,0-21.984787,9.2935991-30.7164001,21.0993118 C65.2847366,5.821527,55.2499847,0,43.2413788,0C18.7586193,0,0,31.8620682,0,65.5862122 C0,86.6896515,10.2095623,100,27.3103466,100c12.3080502,0,21.1600361-5.8025894,36.8965454-33.3103409 c0,0,6.5597382-11.5841255,11.0725021-19.563858c1.5813522,2.5531845,3.2431107,5.3001404,4.9964676,8.2535095 l7.379303,12.4137955C102.0298843,91.8478851,110.039032,100,124.5517273,100 c16.6595764,0,25.9310303-13.4923325,25.9310303-35.0344849 C150.4827576,29.6551723,131.301178,0.0000013,107.9999847,0.0000013z M52.2068977,59.2413788 c-12.7586212,20-17.1724167,24.4827576-24.2758656,24.4827576c-7.3103428,0-11.6551704-6.4178314-11.6551704-17.8620682 c0-24.4827576,12.2068977-49.5172424,26.7586231-49.5172424c7.880127,0,14.4653816,4.5510426,24.5522308,18.9913158 C58.0087967,50.0272293,52.2068977,59.2413788,52.2068977,59.2413788z M100.3597336,56.7235756L91.5367355,42.00877 c-2.3876724-3.8832092-4.6757278-7.451458-6.8838348-10.7230263 c7.951973-12.273531,14.5113449-18.3891907,22.3126144-18.3891907c16.2069016,0,29.1724243,23.8620682,29.1724243,53.1724091 c0,11.1724167-3.6593475,17.6551743-11.2413864,17.6551743 C117.6294937,83.7241364,114.1578674,78.924736,100.3597336,56.7235756z",23 d: "m31.06,125.96c0,10.98 2.41,19.41 5.56,24.51 4.13,6.68 10.29,9.51 16.57,9.51 8.1,0 15.51-2.01 29.79-21.76 11.44-15.83 24.92-38.05 33.99-51.98l15.36-23.6c10.67-16.39 23.02-34.61 37.18-46.96 11.56-10.08 24.03-15.68 36.58-15.68 21.07,0 41.14,12.21 56.5,35.11 16.81,25.08 24.97,56.67 24.97,89.27 0,19.38-3.82,33.62-10.32,44.87-6.28,10.88-18.52,21.75-39.11,21.75l0-31.02c17.63,0 22.03-16.2 22.03-34.74 0-26.42-6.16-55.74-19.73-76.69-9.63-14.86-22.11-23.94-35.84-23.94-14.85,0-26.8,11.2-40.23,31.17-7.14,10.61-14.47,23.54-22.7,38.13l-9.06,16.05c-18.2,32.27-22.81,39.62-31.91,51.75-15.95,21.24-29.57,29.29-47.5,29.29-21.27,0-34.72-9.21-43.05-23.09-6.8-11.31-10.14-26.15-10.14-43.06z",
23 fillRule: "evenodd",24 },
25 {
26 d: "m24.49,37.3c14.24-21.95 34.79-37.3 58.36-37.3 13.65,0 27.22,4.04 41.39,15.61 15.5,12.65 32.02,33.48 52.63,67.81l7.39,12.32c17.84,29.72 27.99,45.01 33.93,52.22 7.64,9.26 12.99,12.02 19.94,12.02 17.63,0 22.03-16.2 22.03-34.74l27.4-.86c0,19.38-3.82,33.62-10.32,44.87-6.28,10.88-18.52,21.75-39.11,21.75-12.8,0-24.14-2.78-36.68-14.61-9.64-9.08-20.91-25.21-29.58-39.71l-25.79-43.08c-12.94-21.62-24.81-37.74-31.68-45.04-7.39-7.85-16.89-17.33-32.05-17.33-12.27,0-22.69,8.61-31.41,21.78z",
27 gradient: {
28 x1: 61,
29 y1: 117,
30 x2: 259,
31 y2: 127,
32 stops: [
33 { offset: 0, color: "#0064e1" },
34 { offset: 0.4, color: "#0064e1" },
35 { offset: 0.83, color: "#0073ee" },
36 { offset: 1, color: "#0082fb" },
37 ],
38 },
39 },
40 {
41 d: "m82.35,31.23c-12.27,0-22.69,8.61-31.41,21.78-12.33,18.61-19.88,46.33-19.88,72.95 0,10.98 2.41,19.41 5.56,24.51l-26.48,17.44c-6.8-11.31-10.14-26.15-10.14-43.06 0-30.75 8.44-62.8 24.49-87.55 14.24-21.95 34.79-37.3 58.36-37.3z",
42 gradient: {
43 x1: 45,
44 y1: 139,
45 x2: 45,
46 y2: 66,
47 stops: [
48 { offset: 0, color: "#0082fb" },
49 { offset: 1, color: "#0064e0" },
50 ],
51 },
24 },52 },
25 ],53 ],
26 },54 },