Fix uploading on the client, add init socket type

This commit is contained in:
Max Leiter 2022-05-30 18:06:14 -07:00
parent c4dea351de
commit a7344b8a4b
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
18 changed files with 208 additions and 52 deletions

View file

@ -174,7 +174,8 @@ export default defineComponent({
} }
socket.once("change-password", (response) => { socket.once("change-password", (response) => {
passwordChangeStatus.value = response; // TODO type
passwordChangeStatus.value = response as any;
}); });
socket.emit("change-password", data); socket.emit("change-password", data);

View file

@ -28,7 +28,7 @@ export default defineComponent({
const networkData = ref<NetworkFormDefaults | null>(null); const networkData = ref<NetworkFormDefaults | null>(null);
const setNetworkData = () => { const setNetworkData = () => {
socket.emit("network:get", route.params.uuid); socket.emit("network:get", String(route.params.uuid));
networkData.value = store.getters.findNetwork(route.params.uuid as string); networkData.value = store.getters.findNetwork(route.params.uuid as string);
}; };
@ -43,13 +43,6 @@ export default defineComponent({
switchToChannel(network.channels[0]); switchToChannel(network.channels[0]);
}; };
// TODO: verify we dont need to watch uuid specifically
// was:
// watch: {
// "$route.params.uuid"() {
// this.setNetworkData();
// },
// },
watch( watch(
() => route.params.uuid, () => route.params.uuid,
(newValue) => { (newValue) => {

View file

@ -199,7 +199,7 @@ export default defineComponent({
socket.emit("search", { socket.emit("search", {
networkUuid: network.value?.uuid, networkUuid: network.value?.uuid,
channelName: channel.value?.name, channelName: channel.value?.name,
searchTerm: route.query.q, searchTerm: String(route.query.q),
offset: offset.value, offset: offset.value,
}); });
}; };
@ -218,7 +218,7 @@ export default defineComponent({
socket.emit("search", { socket.emit("search", {
networkUuid: network.value?.uuid, networkUuid: network.value?.uuid,
channelName: channel.value?.name, channelName: channel.value?.name,
searchTerm: route.query.q, searchTerm: String(route.query.q),
offset: offset.value + 1, offset: offset.value + 1,
}); });
}; };

View file

@ -28,7 +28,7 @@ const timeFormats = {
export default { export default {
colorCodeMap, colorCodeMap,
commands: [], commands: [] as string[],
condensedTypes, condensedTypes,
timeFormats, timeFormats,
// Same value as media query in CSS that forces sidebars to become overlays // Same value as media query in CSS that forces sidebars to become overlays

View file

@ -3,7 +3,7 @@ import storage from "../localStorage";
import {router, navigate} from "../router"; import {router, navigate} from "../router";
import {store} from "../store"; import {store} from "../store";
import location from "../location"; import location from "../location";
let lastServerHash = null; let lastServerHash: string | null = null;
declare global { declare global {
interface Window { interface Window {

View file

@ -2,6 +2,8 @@ import socket from "../socket";
import {store} from "../store"; import {store} from "../store";
socket.on("changelog", function (data) { socket.on("changelog", function (data) {
// TODO
// @ts-ignore
store.commit("versionData", data); store.commit("versionData", data);
store.commit("versionDataExpired", false); store.commit("versionDataExpired", false);

View file

@ -24,7 +24,7 @@ socket.on("init", function (data) {
window.g_TheLoungeRemoveLoading(); window.g_TheLoungeRemoveLoading();
} }
nextTick(() => { void nextTick(() => {
// If we handled query parameters like irc:// links or just general // If we handled query parameters like irc:// links or just general
// connect parameters in public mode, then nothing to do here // connect parameters in public mode, then nothing to do here
if (!handleQueryParams()) { if (!handleQueryParams()) {

View file

@ -1,6 +1,7 @@
import io, {Socket} from "socket.io-client"; import io, {Socket} from "socket.io-client";
import type {ServerToClientEvents, ClientToServerEvents} from "../../src/types/socket-events";
const socket: Socket = io({ const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io({
transports: JSON.parse(document.body.dataset.transports || "['polling', 'websocket']"), transports: JSON.parse(document.body.dataset.transports || "['polling', 'websocket']"),
path: window.location.pathname + "socket.io/", path: window.location.pathname + "socket.io/",
autoConnect: false, autoConnect: false,

View file

@ -63,19 +63,22 @@ export type State = {
sidebarOpen: boolean; sidebarOpen: boolean;
sidebarDragging: boolean; sidebarDragging: boolean;
userlistOpen: boolean; userlistOpen: boolean;
versionData: null | { versionData:
latest: { | null
version: string; | undefined
prerelease: boolean; | {
url: string; latest: {
}; version: string;
current: { prerelease: boolean;
version: string; url: string;
prerelease: boolean; };
url: string; current: {
changelog: string; version: string;
}; prerelease: boolean;
}; url: string;
changelog: string;
};
};
versionStatus: "loading" | "new-version" | "new-packages" | "up-to-date" | "error"; versionStatus: "loading" | "new-version" | "new-packages" | "up-to-date" | "error";
versionDataExpired: boolean; versionDataExpired: boolean;
serverHasSettings: boolean; serverHasSettings: boolean;
@ -388,8 +391,6 @@ const storePattern = {
getters, getters,
}; };
const settingsStore = createSettingsStore(store);
// https://vuex.vuejs.org/guide/typescript-support.html#typing-usestore-composition-function // https://vuex.vuejs.org/guide/typescript-support.html#typing-usestore-composition-function
export const key: InjectionKey<Store<State>> = Symbol(); export const key: InjectionKey<Store<State>> = Symbol();
@ -404,6 +405,8 @@ export type TypedStore = Omit<Store<State>, "getters" | "commit"> & {
export const store = createStore(storePattern) as TypedStore; export const store = createStore(storePattern) as TypedStore;
const settingsStore = createSettingsStore(store);
// Settings module is registered dynamically because it benefits // Settings module is registered dynamically because it benefits
// from a direct reference to the store // from a direct reference to the store
store.registerModule("settings", settingsStore); store.registerModule("settings", settingsStore);

View file

@ -279,15 +279,11 @@ class Uploader {
const initStart = textbox.selectionStart; const initStart = textbox.selectionStart;
if (!initStart) {
throw new Error("Could not find selection start in textbox in upload");
}
// Get the text before the cursor, and add a space if it's not in the beginning // Get the text before the cursor, and add a space if it's not in the beginning
const headToCursor = initStart > 0 ? textbox.value.substr(0, initStart) + " " : ""; const headToCursor = initStart > 0 ? textbox.value.substring(0, initStart) + " " : "";
// Get the remaining text after the cursor // Get the remaining text after the cursor
const cursorToTail = textbox.value.substr(initStart); const cursorToTail = textbox.value.substring(initStart);
// Construct the value until the point where we want the cursor to be // Construct the value until the point where we want the cursor to be
const textBeforeTail = headToCursor + fullURL + " "; const textBeforeTail = headToCursor + fullURL + " ";

View file

@ -5,6 +5,7 @@
] /* Specifies a list of glob patterns that match files to be included in compilation. If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. Requires TypeScript version 2.0 or later. */, ] /* Specifies a list of glob patterns that match files to be included in compilation. If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. Requires TypeScript version 2.0 or later. */,
"files": [ "files": [
"../package.json", "../package.json",
"../src/types/socket-events.d.ts",
"./js/helpers/fullnamemap.json", "./js/helpers/fullnamemap.json",
"./js/helpers/simplemap.json" "./js/helpers/simplemap.json"
] /* If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. When a 'files' property is specified, only those files and those specified by 'include' are included. */, ] /* If no 'files' or 'include' property is present in a tsconfig.json, the compiler defaults to including all files in the containing directory and subdirectories except those specified by 'exclude'. When a 'files' property is specified, only those files and those specified by 'include' are included. */,

View file

@ -17,7 +17,7 @@ import SqliteMessageStorage from "./plugins/messageStorage/sqlite";
import TextFileMessageStorage from "./plugins/messageStorage/text"; import TextFileMessageStorage from "./plugins/messageStorage/text";
import Network, {IgnoreListItem, NetworkWithIrcFramework} from "./models/network"; import Network, {IgnoreListItem, NetworkWithIrcFramework} from "./models/network";
import ClientManager from "./clientManager"; import ClientManager from "./clientManager";
import {MessageStorage, SearchQuery, SearchResponse} from "./plugins/messageStorage/types"; import {MessageStorage, SearchQuery} from "./plugins/messageStorage/types";
const events = [ const events = [
"away", "away",

View file

@ -11,16 +11,7 @@ export default {
fetch, fetch,
checkForUpdates, checkForUpdates,
}; };
export type ChangelogData = {
const versions = {
current: {
version: `v${pkg.version}`,
changelog: undefined,
},
expiresAt: -1,
latest: undefined,
packages: undefined,
} as {
current: { current: {
version: string; version: string;
changelog?: string; changelog?: string;
@ -34,6 +25,16 @@ const versions = {
packages?: boolean; packages?: boolean;
}; };
const versions = {
current: {
version: `v${pkg.version}`,
changelog: undefined,
},
expiresAt: -1,
latest: undefined,
packages: undefined,
} as ChangelogData;
async function fetch() { async function fetch() {
const time = Date.now(); const time = Date.now();

View file

@ -31,7 +31,7 @@ export default <IrcEventHandler>function (irc, network) {
handleMessage(data); handleMessage(data);
}); });
function handleMessage(data) { function handleMessage(data: any) {
let chan; let chan;
let from; let from;
let highlight = false; let highlight = false;

View file

@ -7,9 +7,12 @@ import Config from "../../config";
import Msg, {Message} from "../../models/msg"; import Msg, {Message} from "../../models/msg";
import Client from "../../client"; import Client from "../../client";
import Chan, {Channel} from "../../models/chan"; import Chan, {Channel} from "../../models/chan";
import type {SearchResponse, SqliteMessageStorage as ISqliteMessageStorage} from "./types"; import type {
SearchResponse,
SearchQuery,
SqliteMessageStorage as ISqliteMessageStorage,
} from "./types";
import Network from "../../models/network"; import Network from "../../models/network";
import {SearchQuery} from "./types";
// TODO; type // TODO; type
let sqlite3: any; let sqlite3: any;
@ -69,7 +72,7 @@ class SqliteMessageStorage implements ISqliteMessageStorage {
"SELECT value FROM options WHERE name = 'schema_version'", "SELECT value FROM options WHERE name = 'schema_version'",
(err, row) => { (err, row) => {
if (err) { if (err) {
return log.error(`Failed to retrieve schema version: ${err}`); return log.error(`Failed to retrieve schema version: ${err.toString()}`);
} }
// New table // New table

View file

@ -27,6 +27,12 @@ import packages from "./plugins/packages/index";
import {NetworkWithIrcFramework} from "./models/network"; import {NetworkWithIrcFramework} from "./models/network";
import {ChanType} from "./models/chan"; import {ChanType} from "./models/chan";
import Utils from "./command-line/utils"; import Utils from "./command-line/utils";
import type {
ClientToServerEvents,
ServerToClientEvents,
InterServerEvents,
SocketData,
} from "./types/socket-events";
type ServerOptions = { type ServerOptions = {
dev: boolean; dev: boolean;
@ -212,7 +218,12 @@ export default async function (
return; return;
} }
const sockets = new Server(server, { const sockets = new Server<
ClientToServerEvents,
ServerToClientEvents,
InterServerEvents,
SocketData
>(server, {
wsEngine: wsServer, wsEngine: wsServer,
cookie: false, cookie: false,
serveClient: false, serveClient: false,

View file

@ -1 +1,2 @@
import "./modules"; import "./modules";
import "./socket-events";

143
src/types/socket-events.d.ts vendored Normal file
View file

@ -0,0 +1,143 @@
import {ClientNetwork} from "../../client/js/types";
import Msg from "../models/msg";
import {ChangelogData} from "../plugins/changelog";
import {ClientConfiguration} from "../server";
type Session = {
current: boolean;
active: number;
lastUse: number;
ip: string;
agent: string;
token: string;
};
interface ServerToClientEvents {
"auth:failed": () => void;
"auth:start": (serverHash: number) => void;
"auth:success": () => void;
"upload:auth": (token: string) => void;
changelog: (data: ChangelogData) => void;
"changelog:newversion": () => void;
"change-password": ({success, error}: {success: boolean; error?: any}) => void;
commands: (data: string[]) => void;
configuration: (config: ClientConfiguration) => void;
"push:issubscribed": (isSubscribed: boolean) => void;
"push:unregister": () => void;
"sessions:list": (data: Session[]) => void;
more: ({
chan,
messages,
totalMessages,
}: {
chan: number;
messages: Msg[];
totalMessages: number;
}) => void;
"msg:preview": ({id, chan, preview}: {id: number; chan: number; preview: string}) => void;
init: ({
active,
networks,
token,
}: {
active: number;
networks: ClientNetwork[];
token: string;
}) => void;
}
interface ClientToServerEvents {
"auth:perform": ({user: string, password: string}) => void;
changelog: () => void;
"change-password": ({
old_password: string,
new_password: string,
verify_password: string,
}) => void;
open: (channelId: number) => void;
names: ({target: number}) => void;
input: ({target, text}: {target: number; text: string}) => void;
"upload:auth": () => void;
"upload:ping": (token: string) => void;
"history:clear": ({target}: {target: number}) => void;
"mute:change": ({target, setMutedTo}: {target: number; setMutedTo: boolean}) => void;
"push:register": (subscriptionJson: PushSubscriptionJSON) => void;
"push:unregister": () => void;
"setting:get": () => void;
"setting:set": ({name: string, value: any}) => void;
"sessions:get": () => void;
sort: ({type, order}: {type: string; order: any; target?: string}) => void;
"mentions:dismiss": (msgId: number) => void;
"mentions:dismiss_all": () => void;
"mentions:get": () => void;
more: ({
target,
lastId,
condensed,
}: {
target: number;
lastId: number;
condensed: boolean;
}) => void;
"msg:preview:toggle": ({
target,
messageIds,
shown,
}: {
target: number;
messageIds: number[];
shown: boolean;
}) => void;
"network:get": (uuid: string) => void;
"network:edit": (data: Record<string, any>) => void;
"network:new": (data: Record<string, any>) => void;
"sign-out": (token?: string) => void;
search: ({
networkUuid,
channelName,
searchTerm,
offset,
}: {
networkUuid?: string;
channelName?: string;
searchTerm?: string;
offset: number;
}) => void;
}
interface InterServerEvents {
ping: () => void;
}
interface SocketData {
name: string;
age: number;
}