Hey ho friends of the horizontal storyriver.
I just updated my wiki with my implementation of crazko’s horizontal storyriver and encountered some things that do not work as would like them to.
An update of crazkos original wiki also failed.
My apporach some time ago was to turn crazkos wiki into a plugin which uses the new Layout-feature.
The most unexpected thing is that the reavealwidget (or the qualify widget?!) of the button to switch the layout does not work.
The other thing that does not work are the rotated titles of the compressed tiddlers right and left. The span class (krystal-tiddler__title tc-droppable krystal-tiddler__title–start-active) is there but not shown.
Anybody can help? The win is a horizontal storyriver…
This is the code of the horizontal storyview in $:/plugins/krystal/plugin.js
It seems to be that something in this code is deprecated since the 5.3 update because the class ```
krystal-tiddler__title–start-active is not applied anymore.
/*\
title: $:/plugins/krystal/plugin.js
type: application/javascript
module-type: startup
Sets plugin behavior
\*/
(function () {
const STORY_TIDDLER_TITLE = "$:/StoryList";
const ACTIVE_LINK_CLASS = "krystal-link--active";
const MAXIMIZED_TIDDLER_CLASS = "krystal-tiddler__frame--maximized";
const KRYSTAL_CONFIG = {
highlight: "$:/plugins/krystal/config/highlight",
tiddlerwidth: "$:/plugins/krystal/config/tiddlerwidth",
};
exports.after = ["render"];
exports.startup = function () {
const throttledTiddlerFrameEffects = throttle(tiddlerFrameEffects, 100);
window.addEventListener("scroll", throttledTiddlerFrameEffects, true);
$tw.rootWidget.addEventListener("tm-remove", tiddlersCount);
$tw.rootWidget.addEventListener("tm-scroll", function (event) {
if (event.type === "tm-scroll") {
tiddlersCount(event);
scroll(event);
}
});
$tw.rootWidget.addEventListener("tm-maximize", function (event) {
if (event.type === "tm-maximize") {
tiddlerFullscreen(event.param);
}
});
$tw.hooks.addHook("th-navigating", closeTiddlersToRight);
$tw.wiki.addEventListener("change", highlightOpenTiddlerLinks);
$tw.wiki.addEventListener("change", reinitiateTiddlerFrameEffects);
};
function highlightOpenTiddlerLinks(changes) {
if (!$tw.utils.hop(changes, STORY_TIDDLER_TITLE)) {
return;
}
const config = $tw.wiki.getTiddler(KRYSTAL_CONFIG.highlight);
if (config && config.fields && config.fields.text === "disable") {
return;
}
const tiddlers = $tw.wiki.getTiddlerList(STORY_TIDDLER_TITLE);
Array.from(document.querySelectorAll(`.${ACTIVE_LINK_CLASS}`)).forEach(
(link) => link.classList.remove(ACTIVE_LINK_CLASS)
);
tiddlers.forEach((tiddler) => {
Array.from(
document.querySelectorAll(
`.tc-tiddler-body a[href="#${encodeURIComponent(tiddler)}"]`
)
).forEach((link) => link.classList.add(ACTIVE_LINK_CLASS));
});
}
function tiddlersCount(event) {
const { widget } = event;
var tiddlersCount = widget.list.length;
document.body.style.setProperty("--tiddler-count", tiddlersCount);
}
function scroll(event) {
const { target: tiddlerElement } = event;
const mediaQueryList = window.matchMedia("(min-width: 960px)");
if (mediaQueryList.matches) {
var storyRiver = tiddlerElement.parentElement;
var tiddlers = Array.from(
storyRiver.querySelectorAll("div[data-tiddler-title]")
);
var tiddlerPosition = tiddlers.indexOf(tiddlerElement);
var tiddlerWidth = $tw.wiki.getTiddler(KRYSTAL_CONFIG.tiddlerwidth).fields
.text;
var windowWidth = window.innerWidth;
var position = windowWidth / 2 - tiddlerWidth / 2;
var newRiverPosition = Math.max(
tiddlerPosition * tiddlerWidth - position,
0
);
storyRiver.scroll({ left: newRiverPosition, behavior: "smooth" });
} else {
tiddlerElement.scrollIntoView({ behavior: "smooth" });
}
}
function tiddlerFrameEffects() {
var tiddlers = Array.from(document.querySelectorAll(".tc-tiddler-frame"));
var tiddlersCount = tiddlers.length;
if (tiddlersCount === 0) {
return;
}
var offset = 100;
var tiddlerPadding = Number(
window.getComputedStyle(tiddlers[0]).paddingRight.slice(0, -2)
);
var tiddlerWidth = tiddlers[0].offsetWidth;
var windowWidth = window.innerWidth;
tiddlers.forEach(function (tiddler, i) {
if (i === 0) {
return;
}
var tiddlerTitle = tiddler.querySelector(".krystal-tiddler__title");
// Edit Template
if (!tiddlerTitle) {
return;
}
var previousTiddler = tiddlers[i - 1];
var previousTiddlerTitle = previousTiddler.querySelector(
".krystal-tiddler__title"
);
var x = tiddler.getBoundingClientRect().left;
var start = x < offset + i * tiddlerPadding;
var end =
x > windowWidth - (offset + (tiddlersCount - i) * tiddlerPadding);
var startOverlay = x < tiddlerWidth + (i - 1) * tiddlerPadding;
tiddler.classList.toggle("krystal-tiddler__frame--overlay", startOverlay);
if (previousTiddlerTitle) {
previousTiddlerTitle.classList.toggle(
"krystal-tiddler__title--start-active",
start
);
if (!end) {
previousTiddler.classList.toggle(
"krystal-tiddler__frame--hide",
start
);
}
}
if (start) {
tiddlerTitle.classList.remove("krystal-tiddler__title--end");
}
if (end) {
tiddler.classList.add("krystal-tiddler__frame--overlay");
tiddler.classList.add("krystal-tiddler__frame--hide");
tiddlerTitle.classList.add(
"krystal-tiddler__title--end",
"krystal-tiddler__title--end-active"
);
} else {
if (!startOverlay) {
tiddler.classList.remove("krystal-tiddler__frame--overlay");
}
tiddler.classList.remove("krystal-tiddler__frame--hide");
tiddlerTitle.classList.remove("krystal-tiddler__title--end-active");
}
});
}
function reinitiateTiddlerFrameEffects(changes) {
if (!$tw.utils.hop(changes, STORY_TIDDLER_TITLE)) {
return;
}
var duration = $tw.utils.getAnimationDuration() || 0;
setTimeout(tiddlerFrameEffects, duration);
}
function closeTiddlersToRight(event) {
const storyTiddler = $tw.wiki.getTiddler(STORY_TIDDLER_TITLE);
const tiddlers = $tw.wiki.getTiddlerList(STORY_TIDDLER_TITLE);
const navigateFrom = event.navigateFromTitle;
const navigateTo = event.navigateTo;
const config = $tw.wiki.getTiddler(
"$:/plugins/krystal/config/close"
);
if (config && config.fields && config.fields.text === "disable") {
return event;
}
// Navigating from outside open tiddlers
if (!navigateFrom) {
return event;
}
// Destination tiddler already open
if (tiddlers.indexOf(navigateTo) === -1) {
const currentTiddlerIndex = tiddlers.indexOf(navigateFrom);
const tiddlersToClose = tiddlers.slice(currentTiddlerIndex + 1);
if (tiddlersToClose.length === 0) {
return event;
}
const newStoryList = tiddlers.filter(
(title) => !tiddlersToClose.includes(title)
);
$tw.wiki.addTiddler(
new $tw.Tiddler({ title: STORY_TIDDLER_TITLE }, storyTiddler, {
list: newStoryList,
})
);
}
return event;
}
function tiddlerFullscreen(tiddlerTitle) {
const tiddler = document.querySelector(
`div[data-tiddler-title="${tiddlerTitle}"]`
);
tiddler.classList.toggle(MAXIMIZED_TIDDLER_CLASS);
}
// ---
function throttle(callback, limit) {
var wait = false; // Initially, we're not waiting
return function () {
// We return a throttled function
if (!wait) {
// If we're not waiting
callback.call(); // Execute users function
wait = true; // Prevent future invocations
setTimeout(function () {
// After a period of time
wait = false; // And allow future invocations
}, limit);
}
};
}
})();