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) => {
passwordChangeStatus.value = response;
// TODO type
passwordChangeStatus.value = response as any;
});
socket.emit("change-password", data);

View file

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

View file

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

View file

@ -28,7 +28,7 @@ const timeFormats = {
export default {
colorCodeMap,
commands: [],
commands: [] as string[],
condensedTypes,
timeFormats,
// 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 {store} from "../store";
import location from "../location";
let lastServerHash = null;
let lastServerHash: string | null = null;
declare global {
interface Window {

View file

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

View file

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

View file

@ -1,6 +1,7 @@
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']"),
path: window.location.pathname + "socket.io/",
autoConnect: false,

View file

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

View file

@ -279,15 +279,11 @@ class Uploader {
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
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
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
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. */,
"files": [
"../package.json",
"../src/types/socket-events.d.ts",
"./js/helpers/fullnamemap.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. */,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1 +1,2 @@
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;
}