@silentsheet/core
Version:
a quiet space to write.
149 lines (148 loc) • 3.83 kB
JavaScript
// src/core.ts
var STORAGE_KEY = "silentsheet";
var INITIAL_TIMER_SECONDS = 15 * 60;
var DEFAULT_OPTIONS = {
content: "",
font: "sans-serif",
fontSize: 24,
theme: "sepia",
size: "medium",
timerRunning: false,
timerSeconds: INITIAL_TIMER_SECONDS,
hemingwayMode: false
};
var SilentSheet = class {
constructor(initialState) {
this.timerInterval = null;
this.subscribers = /* @__PURE__ */ new Set();
const savedState = this.loadState();
this.state = {
...DEFAULT_OPTIONS,
...savedState,
...initialState,
timerRunning: false,
timerSeconds: INITIAL_TIMER_SECONDS
};
}
loadState() {
try {
const saved = localStorage.getItem(STORAGE_KEY);
return saved ? JSON.parse(saved) : null;
} catch {
return null;
}
}
saveState() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state));
} catch {
}
}
startTimer() {
if (this.timerInterval) return;
this.timerInterval = setInterval(() => {
if (this.state.timerSeconds <= 0) {
this.stopTimer();
alert("Time is up! Take a moment to review what you've written.");
return;
}
this.state.timerSeconds--;
this.notifySubscribers();
}, 1e3);
}
stopTimer() {
if (this.timerInterval) {
clearInterval(this.timerInterval);
this.timerInterval = null;
}
}
getState() {
return { ...this.state };
}
getActions() {
return {
setContent: (content) => {
if (this.state.hemingwayMode) {
const lines = this.state.content.split("\n");
const newLines = content.split("\n");
if (newLines.length >= lines.length) {
const isValid = lines.every((line, index) => {
if (index === lines.length - 1) return true;
return newLines[index] === line;
});
if (isValid) {
this.state.content = content;
this.saveState();
}
}
} else {
this.state.content = content;
this.saveState();
}
this.notifySubscribers();
},
setFont: (font) => {
this.state.font = font;
this.saveState();
this.notifySubscribers();
},
setFontSize: (size) => {
this.state.fontSize = size;
this.saveState();
this.notifySubscribers();
},
setTheme: (theme) => {
this.state.theme = theme;
this.saveState();
this.notifySubscribers();
},
setSize: (size) => {
this.state.size = size;
this.saveState();
this.notifySubscribers();
},
saveContent: () => {
this.saveState();
},
clearContent: () => {
this.state.content = "";
this.saveState();
this.notifySubscribers();
},
toggleTimer: () => {
if (this.state.timerRunning) {
this.stopTimer();
this.state.timerRunning = false;
this.state.timerSeconds = INITIAL_TIMER_SECONDS;
} else {
this.state.timerRunning = true;
this.startTimer();
}
this.notifySubscribers();
},
resetTimer: () => {
this.stopTimer();
this.state.timerRunning = false;
this.state.timerSeconds = INITIAL_TIMER_SECONDS;
this.notifySubscribers();
},
toggleHemingwayMode: () => {
this.state.hemingwayMode = !this.state.hemingwayMode;
this.saveState();
this.notifySubscribers();
}
};
}
subscribeToUI(callback) {
this.subscribers.add(callback);
return () => {
this.subscribers.delete(callback);
};
}
notifySubscribers() {
this.subscribers.forEach((subscriber) => subscriber());
}
};
export {
SilentSheet
};