feat: sync

This commit is contained in:
Artemy 2023-04-05 14:23:32 +03:00
parent ac79495f83
commit 6af0bfacb2
11 changed files with 94 additions and 17 deletions

View file

@ -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());

View file

@ -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}

View file

@ -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";
} }

View file

@ -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) => (

View file

@ -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;

View file

@ -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 };

View file

@ -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;
} }

View file

@ -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;

View file

@ -47,6 +47,10 @@ let ru = {
CollabEdit: "Совместное редактирование", CollabEdit: "Совместное редактирование",
Password: "Пароль", Password: "Пароль",
CollabEditPassword: "Пароль для совместного редактирования", CollabEditPassword: "Пароль для совместного редактирования",
SyncPassword: "Пароль для синхронизации",
BroadcastSync: "Получение заметок, настроек с другого устройства",
SyncAll: "Отправить данные",
Sync: "Синхронизация",
}; };
export default ru; export default ru;

View file

@ -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);
}} }}
/> />
)} )}

View file

@ -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}