@gentbajko/slopify 3.25.3 → 3.25.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/extension/slopify-studio-chrome.zip +0 -0
- package/dist/extension/slopify-studio-firefox.zip +0 -0
- package/dist/patch-notes/3.25.4.md +5 -0
- package/dist/patch-notes/3.25.5.md +5 -0
- package/dist/patch-notes/index.json +12 -0
- package/dist/slices/rebuild/recipe-shorts.js +12 -4
- package/dist/slices/storage/arrange.js +13 -3
- package/dist/slices/storage/places.js +4 -0
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Slopify 3.25.4
|
|
2
|
+
|
|
3
|
+
Released 17 October 2026.
|
|
4
|
+
|
|
5
|
+
- **The shorts of an older project render after you change it.** On a project made before late September, a saved change (such as turning on Soften breaths) left its shorts waiting forever: they showed as waiting their turn and never started. They now render.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Slopify 3.25.5
|
|
2
|
+
|
|
3
|
+
Released 17 October 2026.
|
|
4
|
+
|
|
5
|
+
- **New videos reach the Upload folder again.** After Delete old versions, Slopify could stop arranging project folders altogether: a remade video, its shorts and everything else new stayed hidden in the project's assets folder while Upload kept the old files. Folders are arranged again, and the newest files take their place in Upload.
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"id": "3.25.5",
|
|
4
|
+
"title": "Slopify 3.25.5",
|
|
5
|
+
"version": "3.25.5",
|
|
6
|
+
"date": "2026-10-17"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"id": "3.25.4",
|
|
10
|
+
"title": "Slopify 3.25.4",
|
|
11
|
+
"version": "3.25.4",
|
|
12
|
+
"date": "2026-10-17"
|
|
13
|
+
},
|
|
2
14
|
{
|
|
3
15
|
"id": "3.25.3",
|
|
4
16
|
"title": "Slopify 3.25.3",
|
|
@@ -220,10 +220,18 @@ export function shortRemakeKey(number) {
|
|
|
220
220
|
}
|
|
221
221
|
// What the pick saved, when its saved answer is the one this plan asks for.
|
|
222
222
|
export function savedPicked(context, pick) {
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
const done = context.manifest.pieces.filter((row) => row.key === pick.key && selectedReference(row) && row.piece.state === "done");
|
|
224
|
+
const piece = done.find((row) => row.fingerprint === pick.fingerprint) ??
|
|
225
|
+
// A project from before an older fingerprint scheme: its output carries the plan's
|
|
226
|
+
// fingerprint and its piece another one. The version's one selected pick belongs with its
|
|
227
|
+
// selected output, so that output's fingerprint vouches for it.
|
|
228
|
+
(done.length === 1 &&
|
|
229
|
+
context.manifest.outputs.some((row) => row.workKey === pick.key &&
|
|
230
|
+
selectedReference(row) &&
|
|
231
|
+
row.fingerprint === pick.fingerprint &&
|
|
232
|
+
(row.state === "ready" || row.state === "outdated"))
|
|
233
|
+
? done[0]
|
|
234
|
+
: undefined);
|
|
227
235
|
return pickedShortsOf(piece?.piece.payload);
|
|
228
236
|
}
|
|
229
237
|
// A clip's saved image prompts, when they answer this plan's request. The request carries
|
|
@@ -70,6 +70,12 @@ export function arrangeProject(deps, projectId) {
|
|
|
70
70
|
places.moves.folderDone(projectId);
|
|
71
71
|
}
|
|
72
72
|
const root = projectDir(paths, projectId);
|
|
73
|
+
// Records of files gone from both their stored path and their place (History that Delete old
|
|
74
|
+
// versions removed, a file deleted by hand) are forgotten, so the names they held are free:
|
|
75
|
+
// otherwise a file moving there is refused and nothing after it is arranged.
|
|
76
|
+
for (const [path, place] of places.placesOf(projectId))
|
|
77
|
+
if (!existsSync(join(root, place)) && !existsSync(join(root, path)))
|
|
78
|
+
places.moves.forget(projectId, path);
|
|
73
79
|
// 2. Each file to its place. Files leaving for History go first, so the new version takes
|
|
74
80
|
// the names they free ("video.mp4", not "video (2).mp4").
|
|
75
81
|
const desired = [...desiredPlaces(db, projectId)].toSorted(([, a], [, b]) => Number(!a.startsWith("History/")) - Number(!b.startsWith("History/")));
|
|
@@ -80,16 +86,20 @@ export function arrangeProject(deps, projectId) {
|
|
|
80
86
|
if (sameBase(at, base) || !existsSync(join(root, at)))
|
|
81
87
|
continue;
|
|
82
88
|
const to = freeName(base, (name) => existsSync(join(root, name)));
|
|
83
|
-
|
|
89
|
+
let recorded = false;
|
|
84
90
|
try {
|
|
91
|
+
places.moves.file(projectId, path, to, placed.get(path));
|
|
92
|
+
recorded = true;
|
|
85
93
|
mkdirSync(dirname(join(root, to)), { recursive: true });
|
|
86
94
|
renameSync(join(root, at), join(root, to));
|
|
87
95
|
places.moves.fileDone(projectId, path);
|
|
88
96
|
moved += 1;
|
|
89
97
|
}
|
|
90
98
|
catch {
|
|
91
|
-
// In use (a player or download on Windows): it stays
|
|
92
|
-
|
|
99
|
+
// In use (a player or download on Windows), or its name refused: it stays where it is and
|
|
100
|
+
// is tried again next time, and the files after it are still arranged.
|
|
101
|
+
if (recorded)
|
|
102
|
+
places.moves.fileUndone(projectId, path);
|
|
93
103
|
}
|
|
94
104
|
}
|
|
95
105
|
removeEmptyFolders(root);
|
|
@@ -81,6 +81,10 @@ export function createPlaces(db) {
|
|
|
81
81
|
if (row !== undefined)
|
|
82
82
|
setFile(projectId, path, { ...row, state: "placed", previous: undefined });
|
|
83
83
|
},
|
|
84
|
+
forget(projectId, path) {
|
|
85
|
+
db.prepare("DELETE FROM file_places WHERE project_id=? AND path=?").run(projectId, path);
|
|
86
|
+
setFile(projectId, path, undefined);
|
|
87
|
+
},
|
|
84
88
|
fileUndone(projectId, path) {
|
|
85
89
|
const row = files.get(projectId)?.get(path);
|
|
86
90
|
if (row?.previous === undefined || row.previous === path) {
|