tauri-app: fix highlights including objectives
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
This commit is contained in:
@@ -41,7 +41,6 @@ const typeToggles = ref<Record<HighlightType, boolean>>({
|
|||||||
kill: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("kill"),
|
kill: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("kill"),
|
||||||
death: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("death"),
|
death: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("death"),
|
||||||
assist: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("assist"),
|
assist: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("assist"),
|
||||||
objective: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("objective"),
|
|
||||||
multi_kill: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("multi_kill"),
|
multi_kill: DEFAULT_HIGHLIGHT_SETTINGS.included_types.includes("multi_kill"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -82,7 +81,6 @@ const activeClipId = computed(() => {
|
|||||||
// Stats
|
// Stats
|
||||||
const killCount = computed(() => props.highlights.filter(h => h.highlight_type === "kill").length);
|
const killCount = computed(() => props.highlights.filter(h => h.highlight_type === "kill").length);
|
||||||
const deathCount = computed(() => props.highlights.filter(h => h.highlight_type === "death").length);
|
const deathCount = computed(() => props.highlights.filter(h => h.highlight_type === "death").length);
|
||||||
const objectiveCount = computed(() => props.highlights.filter(h => h.highlight_type === "objective").length);
|
|
||||||
const multiKillCount = computed(() => props.highlights.filter(h => h.highlight_type === "multi_kill").length);
|
const multiKillCount = computed(() => props.highlights.filter(h => h.highlight_type === "multi_kill").length);
|
||||||
const assistCount = computed(() => props.highlights.filter(h => h.highlight_type === "assist").length);
|
const assistCount = computed(() => props.highlights.filter(h => h.highlight_type === "assist").length);
|
||||||
const totalDuration = computed(() => {
|
const totalDuration = computed(() => {
|
||||||
@@ -174,7 +172,6 @@ function formatClipDuration(clip: HighlightClip): string {
|
|||||||
{ type: 'kill' as HighlightType, label: 'Kills', icon: '⚔️' },
|
{ type: 'kill' as HighlightType, label: 'Kills', icon: '⚔️' },
|
||||||
{ type: 'death' as HighlightType, label: 'Deaths', icon: '💀' },
|
{ type: 'death' as HighlightType, label: 'Deaths', icon: '💀' },
|
||||||
{ type: 'assist' as HighlightType, label: 'Assists', icon: '🤝' },
|
{ type: 'assist' as HighlightType, label: 'Assists', icon: '🤝' },
|
||||||
{ type: 'objective' as HighlightType, label: 'Objectives', icon: '🏰' },
|
|
||||||
{ type: 'multi_kill' as HighlightType, label: 'Multi Kills', icon: '🔥' },
|
{ type: 'multi_kill' as HighlightType, label: 'Multi Kills', icon: '🔥' },
|
||||||
]"
|
]"
|
||||||
:key="typeInfo.type"
|
:key="typeInfo.type"
|
||||||
@@ -230,9 +227,6 @@ function formatClipDuration(clip: HighlightClip): string {
|
|||||||
<div class="stat-pill" v-if="assistCount > 0">
|
<div class="stat-pill" v-if="assistCount > 0">
|
||||||
<span>🤝</span> {{ assistCount }}
|
<span>🤝</span> {{ assistCount }}
|
||||||
</div>
|
</div>
|
||||||
<div class="stat-pill" v-if="objectiveCount > 0">
|
|
||||||
<span>🏰</span> {{ objectiveCount }}
|
|
||||||
</div>
|
|
||||||
<div class="stat-pill" v-if="multiKillCount > 0">
|
<div class="stat-pill" v-if="multiKillCount > 0">
|
||||||
<span>🔥</span> {{ multiKillCount }}
|
<span>🔥</span> {{ multiKillCount }}
|
||||||
</div>
|
</div>
|
||||||
@@ -263,7 +257,7 @@ function formatClipDuration(clip: HighlightClip): string {
|
|||||||
<div v-if="highlights.length === 0" class="empty-highlights">
|
<div v-if="highlights.length === 0" class="empty-highlights">
|
||||||
<div class="empty-icon">🎬</div>
|
<div class="empty-icon">🎬</div>
|
||||||
<p>No highlights detected</p>
|
<p>No highlights detected</p>
|
||||||
<p class="empty-hint">Highlights are generated from kills, deaths, and objectives during the game.</p>
|
<p class="empty-hint">Highlights are generated from kills, deaths, and multi-kills during the game.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Highlights List -->
|
<!-- Highlights List -->
|
||||||
@@ -605,11 +599,6 @@ function formatClipDuration(clip: HighlightClip): string {
|
|||||||
background: rgba(167, 139, 250, 0.08);
|
background: rgba(167, 139, 250, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
.highlight-card.active.objective {
|
|
||||||
border-color: rgba(251, 191, 36, 0.4);
|
|
||||||
background: rgba(251, 191, 36, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
.highlight-card.active.multi_kill {
|
.highlight-card.active.multi_kill {
|
||||||
border-color: rgba(249, 115, 22, 0.4);
|
border-color: rgba(249, 115, 22, 0.4);
|
||||||
background: rgba(249, 115, 22, 0.08);
|
background: rgba(249, 115, 22, 0.08);
|
||||||
|
|||||||
@@ -728,7 +728,7 @@ export type EventCategory =
|
|||||||
/**
|
/**
|
||||||
* The type of highlight clip.
|
* The type of highlight clip.
|
||||||
*/
|
*/
|
||||||
export type HighlightType = "kill" | "death" | "assist" | "objective" | "multi_kill";
|
export type HighlightType = "kill" | "death" | "assist" | "multi_kill";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for highlight generation.
|
* Configuration for highlight generation.
|
||||||
@@ -755,7 +755,7 @@ export const DEFAULT_HIGHLIGHT_SETTINGS: HighlightSettings = {
|
|||||||
buffer_before: 10,
|
buffer_before: 10,
|
||||||
buffer_after: 8,
|
buffer_after: 8,
|
||||||
min_duration: 5,
|
min_duration: 5,
|
||||||
included_types: ["kill", "death", "objective", "multi_kill"],
|
included_types: ["kill", "death", "multi_kill"],
|
||||||
merge_overlapping: true,
|
merge_overlapping: true,
|
||||||
merge_gap_secs: 5,
|
merge_gap_secs: 5,
|
||||||
};
|
};
|
||||||
@@ -808,13 +808,6 @@ export function getKillHighlightType(
|
|||||||
return null; // Not involved — skip
|
return null; // Not involved — skip
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an objective event is relevant (always include objectives).
|
|
||||||
*/
|
|
||||||
export function isObjectiveHighlight(event: TimestampedEvent): boolean {
|
|
||||||
return event.event_type === "objective";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect multi-kills from a sequence of kill events.
|
* Detect multi-kills from a sequence of kill events.
|
||||||
* Returns groups of kills that happened within `windowSecs` seconds.
|
* Returns groups of kills that happened within `windowSecs` seconds.
|
||||||
@@ -878,7 +871,6 @@ export function getHighlightTypeColor(type: HighlightType): string {
|
|||||||
case "kill": return "#4ade80"; // green
|
case "kill": return "#4ade80"; // green
|
||||||
case "death": return "#f87171"; // red
|
case "death": return "#f87171"; // red
|
||||||
case "assist": return "#a78bfa"; // purple
|
case "assist": return "#a78bfa"; // purple
|
||||||
case "objective": return "#fbbf24"; // yellow/gold
|
|
||||||
case "multi_kill": return "#f97316"; // orange
|
case "multi_kill": return "#f97316"; // orange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -891,7 +883,6 @@ export function getHighlightTypeIcon(type: HighlightType): string {
|
|||||||
case "kill": return "⚔️";
|
case "kill": return "⚔️";
|
||||||
case "death": return "💀";
|
case "death": return "💀";
|
||||||
case "assist": return "🤝";
|
case "assist": return "🤝";
|
||||||
case "objective": return "🏰";
|
|
||||||
case "multi_kill": return "🔥";
|
case "multi_kill": return "🔥";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -918,7 +909,6 @@ export function computeHighlights(
|
|||||||
const playerKills: TimestampedEvent[] = [];
|
const playerKills: TimestampedEvent[] = [];
|
||||||
const playerDeaths: TimestampedEvent[] = [];
|
const playerDeaths: TimestampedEvent[] = [];
|
||||||
const playerAssists: TimestampedEvent[] = [];
|
const playerAssists: TimestampedEvent[] = [];
|
||||||
const objectiveEvents: TimestampedEvent[] = [];
|
|
||||||
|
|
||||||
for (const event of events) {
|
for (const event of events) {
|
||||||
if (event.event_type === "kill") {
|
if (event.event_type === "kill") {
|
||||||
@@ -930,8 +920,6 @@ export function computeHighlights(
|
|||||||
} else if (type === "assist" && settings.included_types.includes("assist")) {
|
} else if (type === "assist" && settings.included_types.includes("assist")) {
|
||||||
playerAssists.push(event);
|
playerAssists.push(event);
|
||||||
}
|
}
|
||||||
} else if (event.event_type === "objective" && settings.included_types.includes("objective")) {
|
|
||||||
objectiveEvents.push(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,23 +975,6 @@ export function computeHighlights(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create clips for objectives
|
|
||||||
for (const event of objectiveEvents) {
|
|
||||||
const eventTime = event.video_timestamp[0] + event.video_timestamp[1] / 1e9;
|
|
||||||
const rawData = event.raw_data as { EventName?: string; objectiveType?: string } | null;
|
|
||||||
const objName = rawData?.EventName || rawData?.objectiveType || "Objective";
|
|
||||||
|
|
||||||
clips.push({
|
|
||||||
id: clipId++,
|
|
||||||
start_time: Math.max(0, eventTime - settings.buffer_before),
|
|
||||||
end_time: Math.min(duration, eventTime + settings.buffer_after),
|
|
||||||
highlight_type: "objective",
|
|
||||||
events: [event],
|
|
||||||
title: `Objective`,
|
|
||||||
subtitle: objName.replace(/([A-Z])/g, " $1").trim(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect multi-kills and create clips for them (only if enabled)
|
// Detect multi-kills and create clips for them (only if enabled)
|
||||||
if (settings.included_types.includes("multi_kill")) {
|
if (settings.included_types.includes("multi_kill")) {
|
||||||
const multiKillGroups = detectMultiKills(playerKills);
|
const multiKillGroups = detectMultiKills(playerKills);
|
||||||
@@ -1042,7 +1013,7 @@ export function computeHighlights(
|
|||||||
current.end_time = Math.max(current.end_time, next.end_time);
|
current.end_time = Math.max(current.end_time, next.end_time);
|
||||||
current.events = [...current.events, ...next.events];
|
current.events = [...current.events, ...next.events];
|
||||||
// Keep the "more important" highlight type
|
// Keep the "more important" highlight type
|
||||||
const typePriority: HighlightType[] = ["multi_kill", "kill", "objective", "death", "assist"];
|
const typePriority: HighlightType[] = ["multi_kill", "kill", "death", "assist"];
|
||||||
const currentIdx = typePriority.indexOf(current.highlight_type);
|
const currentIdx = typePriority.indexOf(current.highlight_type);
|
||||||
const nextIdx = typePriority.indexOf(next.highlight_type);
|
const nextIdx = typePriority.indexOf(next.highlight_type);
|
||||||
if (nextIdx < currentIdx) {
|
if (nextIdx < currentIdx) {
|
||||||
|
|||||||
Reference in New Issue
Block a user