mirror of
https://github.com/artegoser/AnoPaper.git
synced 2024-11-06 04:53:56 +03:00
feat: sync
This commit is contained in:
parent
ac79495f83
commit
6af0bfacb2
11 changed files with 94 additions and 17 deletions
12
index.js
12
index.js
|
@ -41,6 +41,18 @@ io.on("connection", (socket) => {
|
||||||
socket.join(room);
|
socket.join(room);
|
||||||
socket.to(room).emit("roomJoined");
|
socket.to(room).emit("roomJoined");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on("leaveRoom", () => {
|
||||||
|
for (let room of rooms) {
|
||||||
|
if (socket.id != room) {
|
||||||
|
socket.leave(room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("broadcastSync", ({ data, room }) => {
|
||||||
|
socket.to(room).emit("broadcastSync", data);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
function CheckBox(props) {
|
function CheckBox(props) {
|
||||||
return (
|
return (
|
||||||
<div className={`form-check m-5 ${props.className}`}>
|
<div className={`m-5 ${props.className}`}>
|
||||||
<input
|
<input
|
||||||
className="form-check-input appearance-none h-3 w-6 duration-500 checked:bg-blue-600 checked:border-blue-600 pr-3 border border-gray-300 rounded-lg mr-1 checked:shadow-lg checked:shadow-blue-600 transition ease-out cursor-pointer"
|
className="appearance-none h-3 w-6 duration-500 checked:bg-blue-600 checked:border-blue-600 pr-3 border border-gray-300 rounded-lg mr-1 checked:shadow-lg checked:shadow-blue-600 transition ease-out cursor-pointer"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
id={props.id}
|
id={props.id}
|
||||||
defaultChecked={props.checked}
|
defaultChecked={props.checked}
|
||||||
|
@ -11,7 +11,7 @@ function CheckBox(props) {
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
title={props.title}
|
title={props.title}
|
||||||
className="form-check-label inline-block cursor-pointer"
|
className="inline-block cursor-pointer"
|
||||||
htmlFor={props.id}
|
htmlFor={props.id}
|
||||||
>
|
>
|
||||||
{props.label}
|
{props.label}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Configuration, OpenAIApi } from "openai";
|
import { Configuration, OpenAIApi } from "openai";
|
||||||
|
|
||||||
async function Complete(setText) {
|
async function Complete(setText, textUpdate) {
|
||||||
document.body.style.cursor = "wait";
|
document.body.style.cursor = "wait";
|
||||||
|
|
||||||
let initText = localStorage.getItem("NoteText");
|
let initText = localStorage.getItem("NoteText");
|
||||||
|
@ -25,6 +25,10 @@ async function Complete(setText) {
|
||||||
localStorage.setItem("NoteText", totalText);
|
localStorage.setItem("NoteText", totalText);
|
||||||
setText(totalText);
|
setText(totalText);
|
||||||
|
|
||||||
|
if (settings.CollabEdit === true) {
|
||||||
|
textUpdate(totalText, true);
|
||||||
|
}
|
||||||
|
|
||||||
document.body.style.cursor = "default";
|
document.body.style.cursor = "default";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,8 @@ function SettingsCheckBox({ label, title, className, settingName, onClick }) {
|
||||||
checked={settings[settingName]}
|
checked={settings[settingName]}
|
||||||
className={className}
|
className={className}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
window.settings[settingName] = e.target.checked;
|
!!settingName && setSetting(settingName, e.target.checked);
|
||||||
localStorage.setObj("settings", window.settings);
|
!!onClick && onClick(e);
|
||||||
onClick && onClick(e);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -39,15 +38,19 @@ function SettingsTextInput({
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
defaultValue={window.settings[settingName]}
|
defaultValue={window.settings[settingName]}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
window.settings[settingName] = e.target.value;
|
!!settingName && setSetting(settingName, e.target.value);
|
||||||
localStorage.setObj("settings", window.settings);
|
!!onChange && onChange(e);
|
||||||
onChange && onChange(e);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSetting(settingName, value) {
|
||||||
|
window.settings[settingName] = value;
|
||||||
|
localStorage.setObj("settings", window.settings);
|
||||||
|
}
|
||||||
|
|
||||||
function SettingsSelectInput({
|
function SettingsSelectInput({
|
||||||
label,
|
label,
|
||||||
className,
|
className,
|
||||||
|
@ -64,9 +67,8 @@ function SettingsSelectInput({
|
||||||
className={`${inputStyle} ${settingsAddInput} m-2 ${className}`}
|
className={`${inputStyle} ${settingsAddInput} m-2 ${className}`}
|
||||||
defaultValue={window.settings[settingName]}
|
defaultValue={window.settings[settingName]}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
window.settings[settingName] = e.target.value;
|
!!settingName && setSetting(settingName, e.target.value);
|
||||||
localStorage.setObj("settings", window.settings);
|
!!onChange && onChange(e);
|
||||||
onChange && onChange(e);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{options.map((option) => (
|
{options.map((option) => (
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { io } from "socket.io-client";
|
import { io } from "socket.io-client";
|
||||||
|
import { reRenderPage } from "./utils";
|
||||||
|
|
||||||
const socket = io();
|
const socket = io();
|
||||||
|
|
||||||
|
@ -8,14 +9,24 @@ function onConnect() {
|
||||||
|
|
||||||
function onDisconnect() {
|
function onDisconnect() {
|
||||||
console.log("Socket disconnected, local mode only");
|
console.log("Socket disconnected, local mode only");
|
||||||
|
window.alreadyConnected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onFooEvent() {
|
function onFooEvent() {
|
||||||
console.log("bar");
|
console.log("bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onSync({ settings, Notes, NoteText, NoteName }) {
|
||||||
|
localStorage.setItem("Notes", Notes);
|
||||||
|
localStorage.setItem("NoteText", NoteText);
|
||||||
|
localStorage.setItem("NoteName", NoteName);
|
||||||
|
localStorage.setItem("settings", settings);
|
||||||
|
reRenderPage();
|
||||||
|
}
|
||||||
|
|
||||||
socket.on("connect", onConnect);
|
socket.on("connect", onConnect);
|
||||||
socket.on("disconnect", onDisconnect);
|
socket.on("disconnect", onDisconnect);
|
||||||
socket.on("foo", onFooEvent);
|
socket.on("foo", onFooEvent);
|
||||||
|
socket.on("broadcastSync", onSync);
|
||||||
|
|
||||||
export default socket;
|
export default socket;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
let inputStyle =
|
let inputStyle =
|
||||||
"form-control block px-3 py-1.5 text-base font-normal text-gray-700 dark:text-white bg-white dark:bg-zinc-900 bg-clip-padding border border-solid border-gray-300 rounded-lg transition ease-in-out focus:border-blue-600 focus:outline-none";
|
"block px-3 py-1.5 text-base font-normal text-gray-700 dark:text-white bg-white dark:bg-zinc-900 bg-clip-padding border border-solid border-gray-300 rounded-lg transition ease-in-out focus:border-blue-600 focus:outline-none";
|
||||||
let settingsAddInput = "w-full lg:w-1/4";
|
let settingsAddInput = "w-full lg:w-1/4";
|
||||||
|
|
||||||
export { inputStyle, settingsAddInput };
|
export { inputStyle, settingsAddInput };
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.md table {
|
.md table {
|
||||||
@apply w-1/2;
|
@apply w-full lg:w-1/2;
|
||||||
border-style: hidden;
|
border-style: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,11 @@ let en = {
|
||||||
AdditionalFeatures: "Additional features",
|
AdditionalFeatures: "Additional features",
|
||||||
CollabEdit: "Collaborative editing",
|
CollabEdit: "Collaborative editing",
|
||||||
Password: "Password",
|
Password: "Password",
|
||||||
|
SyncPassword: "Sync password",
|
||||||
CollabEditPassword: "Password for collaborative editing",
|
CollabEditPassword: "Password for collaborative editing",
|
||||||
|
BroadcastSync: "Getting notes, settings from another device",
|
||||||
|
SyncAll: "Send data to all devices",
|
||||||
|
Sync: "Sync",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default en;
|
export default en;
|
||||||
|
|
|
@ -47,6 +47,10 @@ let ru = {
|
||||||
CollabEdit: "Совместное редактирование",
|
CollabEdit: "Совместное редактирование",
|
||||||
Password: "Пароль",
|
Password: "Пароль",
|
||||||
CollabEditPassword: "Пароль для совместного редактирования",
|
CollabEditPassword: "Пароль для совместного редактирования",
|
||||||
|
SyncPassword: "Пароль для синхронизации",
|
||||||
|
BroadcastSync: "Получение заметок, настроек с другого устройства",
|
||||||
|
SyncAll: "Отправить данные",
|
||||||
|
Sync: "Синхронизация",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ru;
|
export default ru;
|
||||||
|
|
|
@ -209,7 +209,7 @@ function CreateNote() {
|
||||||
className="m-1"
|
className="m-1"
|
||||||
w="w-full"
|
w="w-full"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Complete(setText);
|
Complete(setText, textUpdate);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
} from "../components/settingsInputs";
|
} from "../components/settingsInputs";
|
||||||
import { reRenderPage } from "../components/utils";
|
import { reRenderPage } from "../components/utils";
|
||||||
import Locales from "../localisation/main";
|
import Locales from "../localisation/main";
|
||||||
|
import { ButtonWithIcon } from "../components/button";
|
||||||
|
import { ChevronDoubleRightIcon } from "@heroicons/react/24/outline";
|
||||||
|
|
||||||
function Settings() {
|
function Settings() {
|
||||||
return (
|
return (
|
||||||
|
@ -58,12 +60,50 @@ function Settings() {
|
||||||
placeholder={locals.Password}
|
placeholder={locals.Password}
|
||||||
label={locals.CollabEditPassword}
|
label={locals.CollabEditPassword}
|
||||||
settingName="CollabEditPassword"
|
settingName="CollabEditPassword"
|
||||||
onChange={(e) => {
|
onChange={() => {
|
||||||
window.alreadyConnected = false;
|
window.alreadyConnected = false;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
|
|
||||||
|
<SettingsSection name={locals.Sync}>
|
||||||
|
<SettingsCheckBox
|
||||||
|
label={locals.BroadcastSync}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
socket.emit("joinRoom", settings.syncPassword);
|
||||||
|
} else {
|
||||||
|
socket.emit("leaveRoom");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SettingsTextInput
|
||||||
|
placeholder={locals.Password}
|
||||||
|
label={locals.SyncPassword}
|
||||||
|
secret
|
||||||
|
settingName="SyncPassword"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ButtonWithIcon
|
||||||
|
icon={ChevronDoubleRightIcon}
|
||||||
|
text={locals.SyncAll}
|
||||||
|
className="m-1"
|
||||||
|
w="w-full lg:w-96"
|
||||||
|
onClick={() => {
|
||||||
|
socket.emit("broadcastSync", {
|
||||||
|
data: {
|
||||||
|
settings: localStorage.getItem("settings"),
|
||||||
|
Notes: localStorage.getItem("Notes"),
|
||||||
|
NoteText: localStorage.getItem("NoteText"),
|
||||||
|
NoteName: localStorage.getItem("NoteName"),
|
||||||
|
},
|
||||||
|
room: settings.syncPassword,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SettingsSection>
|
||||||
|
|
||||||
<SettingsSection name={locals.Interface}>
|
<SettingsSection name={locals.Interface}>
|
||||||
<SettingsSelectInput
|
<SettingsSelectInput
|
||||||
label={locals.Language}
|
label={locals.Language}
|
||||||
|
|
Loading…
Reference in a new issue