fix: resolve Pascal editor icons under base path
This commit is contained in:
parent
9cf84c324e
commit
663cb7c67a
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { Icon } from '@iconify/react'
|
import { Icon } from '@iconify/react'
|
||||||
import { memo, useMemo } from 'react'
|
import { memo, useMemo } from 'react'
|
||||||
|
import { withEditorBasePath } from '../../lib/public-asset-path'
|
||||||
import useEditor, { type FloorplanSelectionTool } from '../../store/use-editor'
|
import useEditor, { type FloorplanSelectionTool } from '../../store/use-editor'
|
||||||
import { furnishTools } from '../ui/action-menu/furnish-tools'
|
import { furnishTools } from '../ui/action-menu/furnish-tools'
|
||||||
import { tools as structureTools } from '../ui/action-menu/structure-tools'
|
import { tools as structureTools } from '../ui/action-menu/structure-tools'
|
||||||
@ -108,7 +109,7 @@ export const FloorplanCursorIndicatorOverlay = memo(function FloorplanCursorIndi
|
|||||||
alt=""
|
alt=""
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]"
|
className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]"
|
||||||
src={indicator.iconSrc}
|
src={withEditorBasePath(indicator.iconSrc)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Icon
|
<Icon
|
||||||
@ -142,7 +143,7 @@ export const FloorplanCursorIndicatorOverlay = memo(function FloorplanCursorIndi
|
|||||||
alt=""
|
alt=""
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]"
|
className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]"
|
||||||
src={indicator.iconSrc}
|
src={withEditorBasePath(indicator.iconSrc)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Icon
|
<Icon
|
||||||
|
|||||||
@ -659,7 +659,7 @@ function PaintCursorBadge({
|
|||||||
alt=""
|
alt=""
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]"
|
className="h-5 w-5 object-contain drop-shadow-[0_2px_4px_rgba(0,0,0,0.5)]"
|
||||||
src="/icons/paint.webp"
|
src={withEditorBasePath('/icons/paint.webp')}
|
||||||
style={{
|
style={{
|
||||||
filter: state === 'ready' ? undefined : 'grayscale(1)',
|
filter: state === 'ready' ? undefined : 'grayscale(1)',
|
||||||
opacity: iconOpacity,
|
opacity: iconOpacity,
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import type { Group } from 'three'
|
|||||||
import { furnishTools } from '../../../components/ui/action-menu/furnish-tools'
|
import { furnishTools } from '../../../components/ui/action-menu/furnish-tools'
|
||||||
import { tools } from '../../../components/ui/action-menu/structure-tools'
|
import { tools } from '../../../components/ui/action-menu/structure-tools'
|
||||||
import { EDITOR_LAYER } from '../../../lib/constants'
|
import { EDITOR_LAYER } from '../../../lib/constants'
|
||||||
|
import { withEditorBasePath } from '../../../lib/public-asset-path'
|
||||||
import useEditor from '../../../store/use-editor'
|
import useEditor from '../../../store/use-editor'
|
||||||
import useWallSnapIndicator from '../../../store/use-wall-snap-indicator'
|
import useWallSnapIndicator from '../../../store/use-wall-snap-indicator'
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ export const CursorSphere = forwardRef<Group, CursorSphereProps>(function Cursor
|
|||||||
// eslint-disable-next-line @next/next/no-img-element
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
<img
|
<img
|
||||||
alt={activeToolConfig!.label}
|
alt={activeToolConfig!.label}
|
||||||
src={activeToolConfig!.iconSrc}
|
src={withEditorBasePath(activeToolConfig!.iconSrc)}
|
||||||
style={{
|
style={{
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import { useViewer } from '@pascal-app/viewer'
|
|||||||
import { Icon } from '@iconify/react'
|
import { Icon } from '@iconify/react'
|
||||||
import { Move, Trash2 } from 'lucide-react'
|
import { Move, Trash2 } from 'lucide-react'
|
||||||
import { type ComponentType, lazy, Suspense, useCallback } from 'react'
|
import { type ComponentType, lazy, Suspense, useCallback } from 'react'
|
||||||
|
import { withEditorBasePath } from '../../../lib/public-asset-path'
|
||||||
import { sfxEmitter } from '../../../lib/sfx-bus'
|
import { sfxEmitter } from '../../../lib/sfx-bus'
|
||||||
import { collectZoneContentIds } from '../../../lib/zone-content'
|
import { collectZoneContentIds } from '../../../lib/zone-content'
|
||||||
import useEditor from '../../../store/use-editor'
|
import useEditor from '../../../store/use-editor'
|
||||||
@ -229,7 +230,11 @@ function ParamActionButton({ action, nodeId }: { action: ParamAction<AnyNode>; n
|
|||||||
className={disabled ? 'opacity-40 pointer-events-none' : ''}
|
className={disabled ? 'opacity-40 pointer-events-none' : ''}
|
||||||
icon={
|
icon={
|
||||||
action.iconSrc ? (
|
action.iconSrc ? (
|
||||||
<img alt="" className="h-4 w-4 shrink-0 object-contain" src={action.iconSrc} />
|
<img
|
||||||
|
alt=""
|
||||||
|
className="h-4 w-4 shrink-0 object-contain"
|
||||||
|
src={withEditorBasePath(action.iconSrc)}
|
||||||
|
/>
|
||||||
) : undefined
|
) : undefined
|
||||||
}
|
}
|
||||||
label={action.label}
|
label={action.label}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import {
|
|||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from './../../../components/ui/primitives/tooltip'
|
} from './../../../components/ui/primitives/tooltip'
|
||||||
|
import { withEditorBasePath } from './../../../lib/public-asset-path'
|
||||||
import { cn } from './../../../lib/utils'
|
import { cn } from './../../../lib/utils'
|
||||||
|
|
||||||
export type PanelId = string
|
export type PanelId = string
|
||||||
@ -22,13 +23,13 @@ interface IconRailProps {
|
|||||||
|
|
||||||
const sitePanel: { id: PanelId; iconSrc: string; label: string } = {
|
const sitePanel: { id: PanelId; iconSrc: string; label: string } = {
|
||||||
id: 'site',
|
id: 'site',
|
||||||
iconSrc: '/icons/level.webp',
|
iconSrc: withEditorBasePath('/icons/level.webp'),
|
||||||
label: '场景',
|
label: '场景',
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsPanel: { id: PanelId; iconSrc: string; label: string } = {
|
const settingsPanel: { id: PanelId; iconSrc: string; label: string } = {
|
||||||
id: 'settings',
|
id: 'settings',
|
||||||
iconSrc: '/icons/settings.webp',
|
iconSrc: withEditorBasePath('/icons/settings.webp'),
|
||||||
label: '设置',
|
label: '设置',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,6 +47,7 @@ import {
|
|||||||
squareMetersToAreaUnit,
|
squareMetersToAreaUnit,
|
||||||
} from './../../../../../lib/measurements'
|
} from './../../../../../lib/measurements'
|
||||||
import { createLocalGuideImage } from './../../../../../lib/local-guide-image'
|
import { createLocalGuideImage } from './../../../../../lib/local-guide-image'
|
||||||
|
import { withEditorBasePath } from './../../../../../lib/public-asset-path'
|
||||||
import { cn } from './../../../../../lib/utils'
|
import { cn } from './../../../../../lib/utils'
|
||||||
import useEditor from './../../../../../store/use-editor'
|
import useEditor from './../../../../../store/use-editor'
|
||||||
import { useUploadStore } from '../../../../../store/use-upload'
|
import { useUploadStore } from '../../../../../store/use-upload'
|
||||||
@ -379,13 +380,13 @@ const ReferenceItem = memo(function ReferenceItem({
|
|||||||
<img
|
<img
|
||||||
alt="Scan"
|
alt="Scan"
|
||||||
className="h-3.5 w-3.5 shrink-0 object-contain opacity-70 transition-opacity group-hover/ref:opacity-100"
|
className="h-3.5 w-3.5 shrink-0 object-contain opacity-70 transition-opacity group-hover/ref:opacity-100"
|
||||||
src="/icons/mesh.webp"
|
src={withEditorBasePath('/icons/mesh.webp')}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
alt="Guide"
|
alt="Guide"
|
||||||
className="h-3.5 w-3.5 shrink-0 object-contain opacity-70 transition-opacity group-hover/ref:opacity-100"
|
className="h-3.5 w-3.5 shrink-0 object-contain opacity-70 transition-opacity group-hover/ref:opacity-100"
|
||||||
src="/icons/floorplan.webp"
|
src={withEditorBasePath('/icons/floorplan.webp')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<InlineRenameInput
|
<InlineRenameInput
|
||||||
@ -744,7 +745,7 @@ const LevelItem = memo(function LevelItem({
|
|||||||
'h-4 w-4 shrink-0 object-contain transition-all duration-200',
|
'h-4 w-4 shrink-0 object-contain transition-all duration-200',
|
||||||
!isSelected && 'opacity-60 grayscale',
|
!isSelected && 'opacity-60 grayscale',
|
||||||
)}
|
)}
|
||||||
src="/icons/level.webp"
|
src={withEditorBasePath('/icons/level.webp')}
|
||||||
/>
|
/>
|
||||||
<InlineRenameInput
|
<InlineRenameInput
|
||||||
defaultName={getDefaultLevelName(level.level)}
|
defaultName={getDefaultLevelName(level.level)}
|
||||||
@ -1022,7 +1023,7 @@ const LayerToggle = memo(function LayerToggle() {
|
|||||||
'mb-1 h-6 w-6 transition-all',
|
'mb-1 h-6 w-6 transition-all',
|
||||||
activeTab !== 'structure' && 'opacity-50 grayscale',
|
activeTab !== 'structure' && 'opacity-50 grayscale',
|
||||||
)}
|
)}
|
||||||
src="/icons/room.webp"
|
src={withEditorBasePath('/icons/room.webp')}
|
||||||
/>
|
/>
|
||||||
结构
|
结构
|
||||||
</div>
|
</div>
|
||||||
@ -1058,7 +1059,7 @@ const LayerToggle = memo(function LayerToggle() {
|
|||||||
'mb-1 h-6 w-6 transition-all',
|
'mb-1 h-6 w-6 transition-all',
|
||||||
activeTab !== 'furnish' && 'opacity-50 grayscale',
|
activeTab !== 'furnish' && 'opacity-50 grayscale',
|
||||||
)}
|
)}
|
||||||
src="/icons/couch.webp"
|
src={withEditorBasePath('/icons/couch.webp')}
|
||||||
/>
|
/>
|
||||||
陈设
|
陈设
|
||||||
</div>
|
</div>
|
||||||
@ -1095,7 +1096,7 @@ const LayerToggle = memo(function LayerToggle() {
|
|||||||
'mb-1 h-6 w-6 transition-all',
|
'mb-1 h-6 w-6 transition-all',
|
||||||
activeTab !== 'zones' && 'opacity-50 grayscale',
|
activeTab !== 'zones' && 'opacity-50 grayscale',
|
||||||
)}
|
)}
|
||||||
src="/icons/kitchen.webp"
|
src={withEditorBasePath('/icons/kitchen.webp')}
|
||||||
/>
|
/>
|
||||||
区域
|
区域
|
||||||
</div>
|
</div>
|
||||||
@ -1436,7 +1437,7 @@ const BuildingItem = memo(function BuildingItem({
|
|||||||
'h-5 w-5 object-contain transition-all',
|
'h-5 w-5 object-contain transition-all',
|
||||||
!isBuildingActive && 'opacity-60 grayscale',
|
!isBuildingActive && 'opacity-60 grayscale',
|
||||||
)}
|
)}
|
||||||
src="/icons/building.webp"
|
src={withEditorBasePath('/icons/building.webp')}
|
||||||
/>
|
/>
|
||||||
<span className="truncate font-medium text-sm">{building.name || '建筑'}</span>
|
<span className="truncate font-medium text-sm">{building.name || '建筑'}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -1592,7 +1593,7 @@ export function SitePanel({ projectId, onUploadAsset, onDeleteAsset }: SitePanel
|
|||||||
'h-5 w-5 object-contain transition-all',
|
'h-5 w-5 object-contain transition-all',
|
||||||
phase !== 'site' && 'opacity-60 grayscale',
|
phase !== 'site' && 'opacity-60 grayscale',
|
||||||
)}
|
)}
|
||||||
src="/icons/site-flag.webp"
|
src={withEditorBasePath('/icons/site-flag.webp')}
|
||||||
/>
|
/>
|
||||||
<span className="font-medium text-sm">{siteNode.name || '场地'}</span>
|
<span className="font-medium text-sm">{siteNode.name || '场地'}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import type { AnyNode, AssetInput } from '@pascal-app/core'
|
import type { AnyNode, AssetInput } from '@pascal-app/core'
|
||||||
import type { ReactNode } from 'react'
|
import type { ReactNode } from 'react'
|
||||||
|
import { withEditorBasePath } from '../../lib/public-asset-path'
|
||||||
import { cn } from '../../lib/utils'
|
import { cn } from '../../lib/utils'
|
||||||
|
|
||||||
export type SnapTarget = 'wall' | 'ceiling' | 'roof'
|
export type SnapTarget = 'wall' | 'ceiling' | 'roof'
|
||||||
export type SnapTargetBadgeSize = 'tile' | 'tree'
|
export type SnapTargetBadgeSize = 'tile' | 'tree'
|
||||||
|
|
||||||
const SNAP_TARGET_ICONS: Record<SnapTarget, string> = {
|
const SNAP_TARGET_ICONS: Record<SnapTarget, string> = {
|
||||||
wall: '/icons/wall.webp',
|
wall: withEditorBasePath('/icons/wall.webp'),
|
||||||
ceiling: '/icons/ceiling.webp',
|
ceiling: withEditorBasePath('/icons/ceiling.webp'),
|
||||||
roof: '/icons/roof.webp',
|
roof: withEditorBasePath('/icons/roof.webp'),
|
||||||
}
|
}
|
||||||
|
|
||||||
const SNAP_TARGET_LABELS: Record<SnapTarget, string> = {
|
const SNAP_TARGET_LABELS: Record<SnapTarget, string> = {
|
||||||
|
|||||||
@ -35,6 +35,7 @@ import {
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { flushSync } from 'react-dom'
|
import { flushSync } from 'react-dom'
|
||||||
import { useShallow } from 'zustand/react/shallow'
|
import { useShallow } from 'zustand/react/shallow'
|
||||||
|
import { withEditorBasePath } from '../lib/public-asset-path'
|
||||||
import { cn } from '../lib/utils'
|
import { cn } from '../lib/utils'
|
||||||
import useEditor from '../store/use-editor'
|
import useEditor from '../store/use-editor'
|
||||||
import { ActionButton } from './ui/action-menu/action-button'
|
import { ActionButton } from './ui/action-menu/action-button'
|
||||||
@ -88,25 +89,49 @@ const levelModeBadgeLabels: Record<'manual' | 'stacked' | 'exploded' | 'solo', s
|
|||||||
const wallModeConfig = {
|
const wallModeConfig = {
|
||||||
up: {
|
up: {
|
||||||
icon: (props: any) => (
|
icon: (props: any) => (
|
||||||
<img alt="Full Height" height={28} src="/icons/room.webp" width={28} {...props} />
|
<img
|
||||||
|
alt="Full Height"
|
||||||
|
height={28}
|
||||||
|
src={withEditorBasePath('/icons/room.webp')}
|
||||||
|
width={28}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
label: 'Full Height',
|
label: 'Full Height',
|
||||||
},
|
},
|
||||||
cutaway: {
|
cutaway: {
|
||||||
icon: (props: any) => (
|
icon: (props: any) => (
|
||||||
<img alt="Cutaway" height={28} src="/icons/wallcut.webp" width={28} {...props} />
|
<img
|
||||||
|
alt="Cutaway"
|
||||||
|
height={28}
|
||||||
|
src={withEditorBasePath('/icons/wallcut.webp')}
|
||||||
|
width={28}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
label: 'Cutaway',
|
label: 'Cutaway',
|
||||||
},
|
},
|
||||||
down: {
|
down: {
|
||||||
icon: (props: any) => (
|
icon: (props: any) => (
|
||||||
<img alt="Low" height={28} src="/icons/walllow.webp" width={28} {...props} />
|
<img
|
||||||
|
alt="Low"
|
||||||
|
height={28}
|
||||||
|
src={withEditorBasePath('/icons/walllow.webp')}
|
||||||
|
width={28}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
label: 'Low',
|
label: 'Low',
|
||||||
},
|
},
|
||||||
translucent: {
|
translucent: {
|
||||||
icon: (props: any) => (
|
icon: (props: any) => (
|
||||||
<img alt="Translucent" height={28} src="/icons/wall.png" width={28} {...props} />
|
<img
|
||||||
|
alt="Translucent"
|
||||||
|
height={28}
|
||||||
|
src={withEditorBasePath('/icons/wall.webp')}
|
||||||
|
width={28}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
label: 'Translucent',
|
label: 'Translucent',
|
||||||
},
|
},
|
||||||
@ -508,7 +533,7 @@ export const ViewerOverlay = ({
|
|||||||
<img
|
<img
|
||||||
alt="Scans"
|
alt="Scans"
|
||||||
className="h-[28px] w-[28px] object-contain"
|
className="h-[28px] w-[28px] object-contain"
|
||||||
src="/icons/mesh.webp"
|
src={withEditorBasePath('/icons/mesh.webp')}
|
||||||
/>
|
/>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
)}
|
)}
|
||||||
@ -529,7 +554,7 @@ export const ViewerOverlay = ({
|
|||||||
<img
|
<img
|
||||||
alt="Guides"
|
alt="Guides"
|
||||||
className="h-[28px] w-[28px] object-contain"
|
className="h-[28px] w-[28px] object-contain"
|
||||||
src="/icons/floorplan.webp"
|
src={withEditorBasePath('/icons/floorplan.webp')}
|
||||||
/>
|
/>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
)}
|
)}
|
||||||
@ -640,7 +665,7 @@ export const ViewerOverlay = ({
|
|||||||
<img
|
<img
|
||||||
alt="Orbit Left"
|
alt="Orbit Left"
|
||||||
className="h-[28px] w-[28px] -scale-x-100 object-contain opacity-70 transition-opacity group-hover:opacity-100"
|
className="h-[28px] w-[28px] -scale-x-100 object-contain opacity-70 transition-opacity group-hover:opacity-100"
|
||||||
src="/icons/rotate.webp"
|
src={withEditorBasePath('/icons/rotate.webp')}
|
||||||
/>
|
/>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
|
||||||
@ -655,7 +680,7 @@ export const ViewerOverlay = ({
|
|||||||
<img
|
<img
|
||||||
alt="Orbit Right"
|
alt="Orbit Right"
|
||||||
className="h-[28px] w-[28px] object-contain opacity-70 transition-opacity group-hover:opacity-100"
|
className="h-[28px] w-[28px] object-contain opacity-70 transition-opacity group-hover:opacity-100"
|
||||||
src="/icons/rotate.webp"
|
src={withEditorBasePath('/icons/rotate.webp')}
|
||||||
/>
|
/>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
|
||||||
@ -670,7 +695,7 @@ export const ViewerOverlay = ({
|
|||||||
<img
|
<img
|
||||||
alt="Top View"
|
alt="Top View"
|
||||||
className="h-[28px] w-[28px] object-contain opacity-70 transition-opacity group-hover:opacity-100"
|
className="h-[28px] w-[28px] object-contain opacity-70 transition-opacity group-hover:opacity-100"
|
||||||
src="/icons/topview.webp"
|
src={withEditorBasePath('/icons/topview.webp')}
|
||||||
/>
|
/>
|
||||||
</ActionButton>
|
</ActionButton>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user