@naxodev/opencode-music-player 0.5.4 → 0.5.5
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/index.js +103 -22
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1030,6 +1030,10 @@ function AlbumArtwork(props) {
|
|
|
1030
1030
|
let container;
|
|
1031
1031
|
let paintPending = false;
|
|
1032
1032
|
let disposed = false;
|
|
1033
|
+
let renderedFrameId = -1;
|
|
1034
|
+
let renderedSlot = null;
|
|
1035
|
+
let placementInvalidated = false;
|
|
1036
|
+
let awaitingResizeGeometry = false;
|
|
1033
1037
|
const [nativeVisible, setNativeVisible] = createSignal(false);
|
|
1034
1038
|
const imageDimensions = createMemo(() => pngDimensions(props.artwork.png_base64));
|
|
1035
1039
|
const applyAction = (action) => {
|
|
@@ -1057,25 +1061,69 @@ function AlbumArtwork(props) {
|
|
|
1057
1061
|
const commitPlan = (plan) => {
|
|
1058
1062
|
runtime.state = copyState(plan.nextState);
|
|
1059
1063
|
};
|
|
1064
|
+
const clearInvalidatedPlacement = () => {
|
|
1065
|
+
if (!placementInvalidated)
|
|
1066
|
+
return true;
|
|
1067
|
+
if (runtime.state.transmitted !== 0 && !writeGraphics(renderer, kittyDeletePlacement(runtime.state.transmitted)))
|
|
1068
|
+
return false;
|
|
1069
|
+
runtime.state = {
|
|
1070
|
+
...runtime.state,
|
|
1071
|
+
placement: null
|
|
1072
|
+
};
|
|
1073
|
+
placementInvalidated = false;
|
|
1074
|
+
return true;
|
|
1075
|
+
};
|
|
1076
|
+
const clearPlacement = () => {
|
|
1077
|
+
if (runtime.state.transmitted !== 0 && runtime.state.placement !== null && !writeGraphics(renderer, kittyDeletePlacement(runtime.state.transmitted)))
|
|
1078
|
+
return false;
|
|
1079
|
+
runtime.state = {
|
|
1080
|
+
...runtime.state,
|
|
1081
|
+
placement: null
|
|
1082
|
+
};
|
|
1083
|
+
renderedSlot = null;
|
|
1084
|
+
setNativeVisible(false);
|
|
1085
|
+
return true;
|
|
1086
|
+
};
|
|
1087
|
+
const fitsAvailableSpace = (node) => {
|
|
1088
|
+
for (let parent = node.parent;parent; parent = parent.parent) {
|
|
1089
|
+
if (parent.width < node.width || parent.height < node.height)
|
|
1090
|
+
return false;
|
|
1091
|
+
if (parent.overflow === "visible")
|
|
1092
|
+
continue;
|
|
1093
|
+
if (node.screenX < parent.screenX || node.screenY < parent.screenY || node.screenX + node.width > parent.screenX + parent.width || node.screenY + node.height > parent.screenY + parent.height)
|
|
1094
|
+
return false;
|
|
1095
|
+
}
|
|
1096
|
+
return true;
|
|
1097
|
+
};
|
|
1098
|
+
const fitsViewport = (slot) => slot.screenX >= 0 && slot.screenY >= 0 && slot.screenX + slot.width <= renderer.terminalWidth && slot.screenY + slot.height <= renderer.terminalHeight;
|
|
1099
|
+
const invalidateForResize = () => {
|
|
1100
|
+
if (disposed || !ownership.isCurrent())
|
|
1101
|
+
return;
|
|
1102
|
+
tmuxOffsetCache.offset = null;
|
|
1103
|
+
tmuxOffsetCache.slot = null;
|
|
1104
|
+
renderedFrameId = -1;
|
|
1105
|
+
renderedSlot = null;
|
|
1106
|
+
placementInvalidated = true;
|
|
1107
|
+
awaitingResizeGeometry = true;
|
|
1108
|
+
clearInvalidatedPlacement();
|
|
1109
|
+
setNativeVisible(false);
|
|
1110
|
+
};
|
|
1060
1111
|
const paintNativeImage = () => {
|
|
1061
1112
|
if (!ownership.isCurrent())
|
|
1062
1113
|
return;
|
|
1063
|
-
if (
|
|
1064
|
-
|
|
1065
|
-
writeGraphics(props.context.renderer, kittyDelete(legacyImageIdForResolvedArtwork(props.artwork)));
|
|
1066
|
-
runtime.state = {
|
|
1067
|
-
transmitted: 0,
|
|
1068
|
-
placement: null
|
|
1069
|
-
};
|
|
1070
|
-
}
|
|
1114
|
+
if (!clearInvalidatedPlacement())
|
|
1115
|
+
return;
|
|
1071
1116
|
const kittySupported = supportsKittyGraphics(props.context);
|
|
1117
|
+
if (container && !fitsAvailableSpace(container)) {
|
|
1118
|
+
clearPlacement();
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1072
1121
|
const slotValid = !!container && !container.isDestroyed && container.width >= 1 && container.height >= 1;
|
|
1073
|
-
const slot =
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
} : null;
|
|
1122
|
+
const slot = renderedSlot;
|
|
1123
|
+
if (slot && !fitsViewport(slot)) {
|
|
1124
|
+
clearPlacement();
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1079
1127
|
const offset = terminalOffset(slot);
|
|
1080
1128
|
const imageId = imageIdForArtwork(props.artwork.id);
|
|
1081
1129
|
const x = slot ? slot.screenX + offset.x : 0;
|
|
@@ -1091,6 +1139,20 @@ function AlbumArtwork(props) {
|
|
|
1091
1139
|
width: Math.floor(resolution.width / renderer.terminalWidth),
|
|
1092
1140
|
height: Math.floor(resolution.height / renderer.terminalHeight)
|
|
1093
1141
|
}) : null;
|
|
1142
|
+
if (awaitingResizeGeometry && geometry === null && kittySupported)
|
|
1143
|
+
return;
|
|
1144
|
+
awaitingResizeGeometry = false;
|
|
1145
|
+
if (runtime.identity !== props.artwork.id) {
|
|
1146
|
+
if (!clearPlacement())
|
|
1147
|
+
return;
|
|
1148
|
+
if (!writeGraphics(renderer, kittyDelete(legacyImageIdForResolvedArtwork(props.artwork))))
|
|
1149
|
+
return;
|
|
1150
|
+
runtime.identity = props.artwork.id;
|
|
1151
|
+
runtime.state = {
|
|
1152
|
+
transmitted: 0,
|
|
1153
|
+
placement: null
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1094
1156
|
const plan = planNativeArtworkPlacement({
|
|
1095
1157
|
state: runtime.state,
|
|
1096
1158
|
imageId,
|
|
@@ -1118,20 +1180,28 @@ function AlbumArtwork(props) {
|
|
|
1118
1180
|
if (paintPending || disposed)
|
|
1119
1181
|
return;
|
|
1120
1182
|
paintPending = true;
|
|
1121
|
-
|
|
1122
|
-
paintPending = false;
|
|
1123
|
-
if (!disposed && ownership.isCurrent())
|
|
1124
|
-
paintNativeImage();
|
|
1125
|
-
}).catch((error) => {
|
|
1183
|
+
queueMicrotask(() => {
|
|
1126
1184
|
paintPending = false;
|
|
1127
|
-
if (
|
|
1185
|
+
if (disposed || !ownership.isCurrent())
|
|
1186
|
+
return;
|
|
1187
|
+
try {
|
|
1188
|
+
if (renderedFrameId !== renderer.frameId)
|
|
1189
|
+
clearPlacement();
|
|
1190
|
+
else
|
|
1191
|
+
paintNativeImage();
|
|
1192
|
+
} catch (error) {
|
|
1128
1193
|
console.error("Failed to paint music artwork", error);
|
|
1194
|
+
}
|
|
1129
1195
|
});
|
|
1130
1196
|
};
|
|
1131
|
-
onMount(() =>
|
|
1197
|
+
onMount(() => {
|
|
1198
|
+
renderer.on("frame", scheduleNativeImage);
|
|
1199
|
+
renderer.on("resize", invalidateForResize);
|
|
1200
|
+
});
|
|
1132
1201
|
onCleanup(() => {
|
|
1133
1202
|
disposed = true;
|
|
1134
|
-
|
|
1203
|
+
renderer.off("frame", scheduleNativeImage);
|
|
1204
|
+
renderer.off("resize", invalidateForResize);
|
|
1135
1205
|
setTimeout(() => {
|
|
1136
1206
|
cleanupNativeArtwork(ownership, () => {
|
|
1137
1207
|
if (!renderer.isDestroyed)
|
|
@@ -1147,6 +1217,17 @@ function AlbumArtwork(props) {
|
|
|
1147
1217
|
return (() => {
|
|
1148
1218
|
var _el$ = _$createElement("box");
|
|
1149
1219
|
_$use((value) => container = value, _el$);
|
|
1220
|
+
_$setProp(_el$, "renderAfter", () => {
|
|
1221
|
+
if (!container)
|
|
1222
|
+
return;
|
|
1223
|
+
renderedFrameId = renderer.frameId;
|
|
1224
|
+
renderedSlot = {
|
|
1225
|
+
screenX: container.screenX,
|
|
1226
|
+
screenY: container.screenY,
|
|
1227
|
+
width: container.width,
|
|
1228
|
+
height: container.height
|
|
1229
|
+
};
|
|
1230
|
+
});
|
|
1150
1231
|
_$setProp(_el$, "width", 24);
|
|
1151
1232
|
_$setProp(_el$, "height", 12);
|
|
1152
1233
|
_$setProp(_el$, "flexDirection", "column");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naxodev/opencode-music-player",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.5",
|
|
4
4
|
"description": "macOS system Now Playing controls for the OpenCode 2 TUI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"validate": "bun run format:check && bun run check && bun run test && bun run pack:check"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@naxodev/music-core": "^0.2.
|
|
63
|
+
"@naxodev/music-core": "^0.2.2",
|
|
64
64
|
"pngjs": "^7.0.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|