feat: highlight link to other quest or copy item name in quest details
This commit is contained in:
@ -53,6 +53,7 @@ export default function GuideView() {
|
||||
questUrl={selectedQuest.url}
|
||||
profileId={activeProfileId}
|
||||
onClose={() => setSelectedQuest(null)}
|
||||
onSelectQuest={setSelectedQuest}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -380,11 +381,6 @@ function QuestRow({ quest, completed, onToggle, onSelect, indent }: {
|
||||
>
|
||||
{quest.name}
|
||||
</span>
|
||||
{quest.combat_indicators.map((ci, i) => (
|
||||
<span key={i} style={{ fontSize: "11px", color: "#94a3b8", whiteSpace: "nowrap", flexShrink: 0 }}>
|
||||
{combatIcon(ci.combat_type)} x{ci.count}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{hasPreviewSection && (
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { openUrl } from "@tauri-apps/plugin-opener";
|
||||
import { QuestStep } from "../types";
|
||||
import { QuestStep, RichSegment } from "../types";
|
||||
import { TextWithCoords } from "./TextWithCoords";
|
||||
|
||||
const DPLN_BASE = "https://www.dofuspourlesnoobs.com";
|
||||
|
||||
interface Props {
|
||||
questName: string;
|
||||
questUrl: string | null;
|
||||
profileId: string;
|
||||
onClose: () => void;
|
||||
onSelectQuest?: (quest: { name: string; url: string | null }) => void;
|
||||
}
|
||||
|
||||
export default function QuestDetailPanel({ questName, questUrl, profileId, onClose }: Props) {
|
||||
export default function QuestDetailPanel({ questName, questUrl, profileId, onClose, onSelectQuest }: Props) {
|
||||
const [steps, setSteps] = useState<QuestStep[]>([]);
|
||||
const [completedSteps, setCompletedSteps] = useState<Set<number>>(new Set());
|
||||
const [expandedSteps, setExpandedSteps] = useState<Set<number>>(new Set());
|
||||
@ -187,9 +190,6 @@ export default function QuestDetailPanel({ questName, questUrl, profileId, onClo
|
||||
|
||||
const lines = step.text.split('\n').filter(l => l.trim().length > 0);
|
||||
const needsTruncate = lines.length > 4;
|
||||
const displayText = needsTruncate && !expanded
|
||||
? lines.slice(0, 4).join('\n')
|
||||
: step.text;
|
||||
|
||||
return (
|
||||
<div key={step.index} onClick={() => toggleStep(step.index)} style={{
|
||||
@ -213,7 +213,10 @@ export default function QuestDetailPanel({ questName, questUrl, profileId, onClo
|
||||
fontSize: "12px", color: "#94a3b8",
|
||||
lineHeight: 1.6, whiteSpace: "pre-wrap", wordBreak: "break-word",
|
||||
}}>
|
||||
<TextWithCoords text={displayText} />
|
||||
{step.rich_text.length > 0 && (expanded || !needsTruncate)
|
||||
? <RichText segments={step.rich_text} onSelectQuest={onSelectQuest} />
|
||||
: <TextWithCoords text={needsTruncate && !expanded ? lines.slice(0, 4).join('\n') : step.text} />
|
||||
}
|
||||
</div>
|
||||
|
||||
{needsTruncate && (
|
||||
@ -255,6 +258,42 @@ export default function QuestDetailPanel({ questName, questUrl, profileId, onClo
|
||||
);
|
||||
}
|
||||
|
||||
function RichText({
|
||||
segments,
|
||||
onSelectQuest,
|
||||
}: {
|
||||
segments: RichSegment[];
|
||||
onSelectQuest?: (quest: { name: string; url: string | null }) => void;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
{segments.map((seg, i) => {
|
||||
if (seg.type === "QuestLink") {
|
||||
return (
|
||||
<span
|
||||
key={i}
|
||||
onClick={e => {
|
||||
e.stopPropagation();
|
||||
onSelectQuest?.({ name: seg.text, url: DPLN_BASE + seg.href });
|
||||
}}
|
||||
style={{
|
||||
color: "#4a9eff",
|
||||
textDecoration: "underline",
|
||||
cursor: "pointer",
|
||||
}}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = "#93c5fd")}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = "#4a9eff")}
|
||||
>
|
||||
{seg.text}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <TextWithCoords key={i} text={seg.text} />;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function QuestHeader({ step }: { step: QuestStep }) {
|
||||
return (
|
||||
<div style={{
|
||||
|
||||
Reference in New Issue
Block a user