saltfish 0.3.37 → 0.3.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/services/PlaylistOrchestrator.d.ts.map +1 -1
- package/dist/managers/CursorManager.d.ts +21 -1
- package/dist/managers/CursorManager.d.ts.map +1 -1
- package/dist/managers/InteractionManager.d.ts.map +1 -1
- package/dist/player.js +2 -2
- package/dist/player.min.js +2 -2
- package/dist/saltfish-playlist-player.es.js +117 -5
- package/dist/saltfish-playlist-player.umd.js +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -2845,10 +2845,13 @@ class PlaylistOrchestrator {
|
|
|
2845
2845
|
if (updatedStore.manifest.cursorColor) {
|
|
2846
2846
|
this.managers.cursorManager.setColor(updatedStore.manifest.cursorColor);
|
|
2847
2847
|
}
|
|
2848
|
+
if (updatedStore.manifest.cursorLabel) {
|
|
2849
|
+
this.managers.cursorManager.setLabel(updatedStore.manifest.cursorLabel);
|
|
2850
|
+
}
|
|
2848
2851
|
const isTriggeredAutomatically = finalOptions._triggeredByTriggerManager === true;
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
if (updatedStore.manifest.compactFirstStep
|
|
2852
|
+
const isFirstStep = updatedStore.currentStepId === ((_e = updatedStore.manifest.steps[0]) == null ? void 0 : _e.id);
|
|
2853
|
+
if (updatedStore.manifest.idleMode && isFirstStep) {
|
|
2854
|
+
if (updatedStore.manifest.compactFirstStep) {
|
|
2852
2855
|
const playerElement = this.managers.uiManager.getPlayerElement();
|
|
2853
2856
|
playerElement == null ? void 0 : playerElement.classList.add("sf-player--compact");
|
|
2854
2857
|
if (updatedStore.manifest.compactLabel) {
|
|
@@ -6713,6 +6716,9 @@ class CursorManager {
|
|
|
6713
6716
|
__publicField(this, "isSelectionMode", false);
|
|
6714
6717
|
__publicField(this, "selectionPadding", 4);
|
|
6715
6718
|
// Default padding in pixels
|
|
6719
|
+
// Label element for cursor name/text
|
|
6720
|
+
__publicField(this, "labelElement", null);
|
|
6721
|
+
__publicField(this, "labelText", null);
|
|
6716
6722
|
// Selection drag properties
|
|
6717
6723
|
__publicField(this, "dragStartX", null);
|
|
6718
6724
|
__publicField(this, "dragStartY", null);
|
|
@@ -7107,9 +7113,12 @@ class CursorManager {
|
|
|
7107
7113
|
<path d="M3.5 3.5L10.5 20.5L13.3 13.3L20.5 10.5L3.5 3.5Z" fill="#ff7614" stroke="white" stroke-width="0.7" stroke-linejoin="round" stroke-linecap="round" filter="url(#cursor-shadow)" />
|
|
7108
7114
|
</svg>
|
|
7109
7115
|
`;
|
|
7116
|
+
this.labelElement = document.createElement("div");
|
|
7117
|
+
this.labelElement.className = "sf-cursor-label";
|
|
7110
7118
|
this.selectionElement = document.createElement("div");
|
|
7111
7119
|
this.selectionElement.className = "sf-selection";
|
|
7112
7120
|
document.body.appendChild(this.cursor);
|
|
7121
|
+
document.body.appendChild(this.labelElement);
|
|
7113
7122
|
document.body.appendChild(this.selectionElement);
|
|
7114
7123
|
this.flashlightOverlay = document.createElement("div");
|
|
7115
7124
|
this.flashlightOverlay.className = "sf-flashlight-overlay";
|
|
@@ -7196,6 +7205,35 @@ class CursorManager {
|
|
|
7196
7205
|
.sf-flashlight-overlay--visible {
|
|
7197
7206
|
display: block;
|
|
7198
7207
|
}
|
|
7208
|
+
|
|
7209
|
+
.sf-cursor-label {
|
|
7210
|
+
position: fixed;
|
|
7211
|
+
top: 0;
|
|
7212
|
+
left: 0;
|
|
7213
|
+
z-index: 9999999;
|
|
7214
|
+
pointer-events: none;
|
|
7215
|
+
display: none;
|
|
7216
|
+
will-change: transform;
|
|
7217
|
+
transform: var(--sf-cursor-label-transform, translate(0, 0));
|
|
7218
|
+
opacity: var(--sf-cursor-opacity, 1);
|
|
7219
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
|
7220
|
+
font-size: 13px;
|
|
7221
|
+
font-weight: 500;
|
|
7222
|
+
color: var(--sf-cursor-label-text, #fff);
|
|
7223
|
+
background: var(--sf-cursor-label-bg, #ff7614);
|
|
7224
|
+
padding: 4px 10px;
|
|
7225
|
+
border-radius: 12px;
|
|
7226
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
7227
|
+
white-space: nowrap;
|
|
7228
|
+
margin: 0;
|
|
7229
|
+
border: 0;
|
|
7230
|
+
box-sizing: border-box;
|
|
7231
|
+
line-height: 1.4;
|
|
7232
|
+
}
|
|
7233
|
+
|
|
7234
|
+
.sf-cursor-label--visible {
|
|
7235
|
+
display: block;
|
|
7236
|
+
}
|
|
7199
7237
|
`;
|
|
7200
7238
|
try {
|
|
7201
7239
|
const sheet = new CSSStyleSheet();
|
|
@@ -7305,6 +7343,10 @@ class CursorManager {
|
|
|
7305
7343
|
this.cursor.classList.add("sf-cursor--visible");
|
|
7306
7344
|
this.cursor.style.setProperty("--sf-cursor-transform", `translate(${x}px, ${y}px) translate(-50%, -50%)`);
|
|
7307
7345
|
}
|
|
7346
|
+
if (this.labelElement && this.labelText) {
|
|
7347
|
+
this.labelElement.classList.add("sf-cursor-label--visible");
|
|
7348
|
+
this.labelElement.style.setProperty("--sf-cursor-label-transform", `translate(${x + 24}px, ${y + 8}px)`);
|
|
7349
|
+
}
|
|
7308
7350
|
if (this.flashlightOverlay) {
|
|
7309
7351
|
this.flashlightOverlay.classList.add("sf-flashlight-overlay--visible");
|
|
7310
7352
|
this.flashlightOverlay.style.setProperty("--sf-flashlight-bg", `radial-gradient(circle 150px at ${x}px ${y}px, transparent 0%, rgba(0, 0, 0, 0.4) 100%)`);
|
|
@@ -7317,6 +7359,9 @@ class CursorManager {
|
|
|
7317
7359
|
if (this.cursor) {
|
|
7318
7360
|
this.cursor.classList.remove("sf-cursor--visible");
|
|
7319
7361
|
}
|
|
7362
|
+
if (this.labelElement) {
|
|
7363
|
+
this.labelElement.classList.remove("sf-cursor-label--visible");
|
|
7364
|
+
}
|
|
7320
7365
|
if (this.selectionElement) {
|
|
7321
7366
|
this.selectionElement.classList.remove("sf-selection--visible");
|
|
7322
7367
|
}
|
|
@@ -7902,6 +7947,11 @@ class CursorManager {
|
|
|
7902
7947
|
this.cursor.remove();
|
|
7903
7948
|
this.cursor = null;
|
|
7904
7949
|
}
|
|
7950
|
+
if (this.labelElement && this.labelElement.parentNode) {
|
|
7951
|
+
this.labelElement.remove();
|
|
7952
|
+
this.labelElement = null;
|
|
7953
|
+
}
|
|
7954
|
+
this.labelText = null;
|
|
7905
7955
|
if (this.selectionElement && this.selectionElement.parentNode) {
|
|
7906
7956
|
this.selectionElement.remove();
|
|
7907
7957
|
this.selectionElement = null;
|
|
@@ -7922,7 +7972,7 @@ class CursorManager {
|
|
|
7922
7972
|
document.documentElement.style.removeProperty("--sf-cursor-y");
|
|
7923
7973
|
}
|
|
7924
7974
|
/**
|
|
7925
|
-
* Sets the color of the cursor SVG
|
|
7975
|
+
* Sets the color of the cursor SVG, selection highlight, and label
|
|
7926
7976
|
* @param color - The color to set (hex, rgb, etc)
|
|
7927
7977
|
*/
|
|
7928
7978
|
setColor(color) {
|
|
@@ -7946,6 +7996,46 @@ class CursorManager {
|
|
|
7946
7996
|
const rgbaBackground = this.colorToRgba(color, 0);
|
|
7947
7997
|
this.selectionElement.style.setProperty("--sf-selection-bg-color", rgbaBackground);
|
|
7948
7998
|
}
|
|
7999
|
+
if (this.labelElement) {
|
|
8000
|
+
this.labelElement.style.setProperty("--sf-cursor-label-bg", color);
|
|
8001
|
+
const textColor = this.getContrastingTextColor(color);
|
|
8002
|
+
this.labelElement.style.setProperty("--sf-cursor-label-text", textColor);
|
|
8003
|
+
}
|
|
8004
|
+
}
|
|
8005
|
+
/**
|
|
8006
|
+
* Calculates whether white or black text provides better contrast against a background color
|
|
8007
|
+
* Uses relative luminance calculation for accessibility
|
|
8008
|
+
* @param bgColor - The background color (hex, rgb, etc)
|
|
8009
|
+
* @returns '#fff' for dark backgrounds, '#333' for light backgrounds
|
|
8010
|
+
*/
|
|
8011
|
+
getContrastingTextColor(bgColor) {
|
|
8012
|
+
const rgb = this.parseColorToRgb(bgColor);
|
|
8013
|
+
if (!rgb) {
|
|
8014
|
+
return "#fff";
|
|
8015
|
+
}
|
|
8016
|
+
const luminance = (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1e3;
|
|
8017
|
+
return luminance > 150 ? "#333" : "#fff";
|
|
8018
|
+
}
|
|
8019
|
+
/**
|
|
8020
|
+
* Parses a color string to RGB values
|
|
8021
|
+
* @param color - The color to parse (hex, rgb, rgba)
|
|
8022
|
+
* @returns RGB object or null if parsing fails
|
|
8023
|
+
*/
|
|
8024
|
+
parseColorToRgb(color) {
|
|
8025
|
+
const tempElement = document.createElement("div");
|
|
8026
|
+
tempElement.style.color = color;
|
|
8027
|
+
document.body.appendChild(tempElement);
|
|
8028
|
+
const computedColor = window.getComputedStyle(tempElement).color;
|
|
8029
|
+
document.body.removeChild(tempElement);
|
|
8030
|
+
const rgbMatch = computedColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
8031
|
+
if (rgbMatch) {
|
|
8032
|
+
return {
|
|
8033
|
+
r: parseInt(rgbMatch[1], 10),
|
|
8034
|
+
g: parseInt(rgbMatch[2], 10),
|
|
8035
|
+
b: parseInt(rgbMatch[3], 10)
|
|
8036
|
+
};
|
|
8037
|
+
}
|
|
8038
|
+
return null;
|
|
7949
8039
|
}
|
|
7950
8040
|
/**
|
|
7951
8041
|
* Converts a color string (hex, rgb, rgba) to rgba format with specified opacity
|
|
@@ -7968,6 +8058,25 @@ class CursorManager {
|
|
|
7968
8058
|
}
|
|
7969
8059
|
return color;
|
|
7970
8060
|
}
|
|
8061
|
+
/**
|
|
8062
|
+
* Sets the label text to display beside the cursor
|
|
8063
|
+
* @param label - The label text to display (e.g., avatar name), or null to hide
|
|
8064
|
+
*/
|
|
8065
|
+
setLabel(label) {
|
|
8066
|
+
var _a;
|
|
8067
|
+
this.labelText = label;
|
|
8068
|
+
if (this.labelElement) {
|
|
8069
|
+
if (label) {
|
|
8070
|
+
this.labelElement.textContent = label;
|
|
8071
|
+
if ((_a = this.cursor) == null ? void 0 : _a.classList.contains("sf-cursor--visible")) {
|
|
8072
|
+
this.labelElement.classList.add("sf-cursor-label--visible");
|
|
8073
|
+
}
|
|
8074
|
+
} else {
|
|
8075
|
+
this.labelElement.textContent = "";
|
|
8076
|
+
this.labelElement.classList.remove("sf-cursor-label--visible");
|
|
8077
|
+
}
|
|
8078
|
+
}
|
|
8079
|
+
}
|
|
7971
8080
|
}
|
|
7972
8081
|
class InteractionManager {
|
|
7973
8082
|
constructor() {
|
|
@@ -8262,7 +8371,10 @@ class InteractionManager {
|
|
|
8262
8371
|
anonymousData.watchedPlaylists[currentStore.manifest.id] = {
|
|
8263
8372
|
status: "in_progress",
|
|
8264
8373
|
currentStepId: buttonConfig.action.target,
|
|
8374
|
+
timestamp: Date.now(),
|
|
8375
|
+
// Use timestamp for consistency with checkAndResumeInProgressPlaylist
|
|
8265
8376
|
lastProgressAt: Date.now()
|
|
8377
|
+
// Keep for backward compatibility
|
|
8266
8378
|
};
|
|
8267
8379
|
this.storageManager.setAnonymousUserData(anonymousData);
|
|
8268
8380
|
log(`InteractionManager: Updated anonymous user watchedPlaylists for step ${buttonConfig.action.target}`);
|
|
@@ -11784,7 +11896,7 @@ const SaltfishPlayer$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.de
|
|
|
11784
11896
|
__proto__: null,
|
|
11785
11897
|
SaltfishPlayer
|
|
11786
11898
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
11787
|
-
const version = "0.3.
|
|
11899
|
+
const version = "0.3.40";
|
|
11788
11900
|
const packageJson = {
|
|
11789
11901
|
version
|
|
11790
11902
|
};
|