Skip to content

Commit f1d85b6

Browse files
committed
Update reconnection UI components
1 parent c72058c commit f1d85b6

7 files changed

Lines changed: 107 additions & 106 deletions

File tree

src/app/types/modules/irc-framework/irc-framework.d.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ declare module 'irc-framework' {
55
import MiddlewareHandler from 'middleware-handler';
66

77
export class Client extends EventEmitter {
8-
constructor(options: ClientConstructorParameters);
8+
constructor(options?: ClientConstructorParameters);
99

1010
static setDefaultTransport<Transport extends typeof BaseTransport>(transport: Transport): void;
1111

@@ -33,7 +33,7 @@ declare module 'irc-framework' {
3333
) => void,
3434
): this;
3535

36-
connect(connect_options?: unknown): void;
36+
connect(connect_options?: ClientConstructorParameters): void;
3737

3838
/**
3939
* Proxy the command handler events onto the client object, with some added sugar
@@ -137,10 +137,16 @@ declare module 'irc-framework' {
137137
on(eventType: 'userlist', cb: (event: UserListEventArgs) => void): this;
138138

139139
on(eventType: 'monitorList', cb: (event: MonitorListEventArgs) => void): this;
140-
on(eventType: 'whowas', cb: (event: WhoIsEventArgs) => void): this;
140+
on(eventType: 'whois', cb: (event: WhoIsEventArgs) => void): this;
141141
on(eventType: 'whowas', cb: (event: WhoWasEventArgs) => void): this;
142142

143143
on(eventType: 'registered', cb: (event: RegisteredEventArgs) => void): this;
144+
on(eventType: 'connected', cb: (event: RegisteredEventArgs) => void): this;
145+
on(eventType: 'connecting', cb: () => void): this;
146+
on(
147+
eventType: 'reconnecting',
148+
cb: (event: { attempt: number; max_retries: number; wait: number }) => void,
149+
): this;
144150

145151
on(eventType: 'quit', cb: (event: QuitEventArgs) => void): this;
146152
on(eventType: 'part', cb: (event: QuitEventArgs) => void): this;
@@ -451,7 +457,7 @@ declare module 'irc-framework' {
451457
enable_echomessage?: boolean;
452458
message_max_length?: number;
453459
auto_reconnect?: boolean;
454-
auto_reconnect_wait?: number;
460+
auto_reconnect_max_wait?: number;
455461
auto_reconnect_max_retries?: number;
456462
ping_interval?: number;
457463
ping_timeout?: number;
Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
<template>
2-
<button
2+
<BButton
3+
class="w-100"
34
type="button"
4-
:class="{ active: tryingToConnect }"
5-
class="connect-button btn btn-primary w-100 font-weight-bolder"
6-
style="font-size:13px;"
7-
@click="connect"
5+
variant="primary"
6+
@click="reconnect"
7+
:loading="tryingToConnect"
8+
loading-text="Connecting..."
9+
>Reconnect</BButton
810
>
9-
Reconnect
10-
</button>
1111
</template>
12-
<script lang="ts" setup>
13-
import { vxm } from '#store/vxm';
14-
import { computed } from 'vue';
12+
<script setup lang="ts">
13+
import { useIrcStore } from '#stores';
14+
import { BButton } from 'bootstrap-vue-next';
15+
import { computed } from 'vue';
1516
16-
const tryingToConnect = computed(() => vxm.chat.connectionData.tryingToConnect);
17-
18-
function connect() {
19-
vxm.chat.connect();
20-
}
17+
const irc = useIrcStore();
18+
const tryingToConnect = computed(() => irc.connectionStatus === 'connecting');
19+
function reconnect() {
20+
irc.reconnect();
21+
}
2122
</script>
Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,50 @@
11
<template>
2-
<li
3-
v-if="!connectionData.connected && !connectionData.firstConnection && !disconnected"
4-
id="chat-loading"
5-
style="list-style-type: none"
6-
>
7-
<img
8-
src="https://s3.amazonaws.com/eterna/icon_img/loading.gif"
9-
class="loading-icon mr-auto ml-auto align-middle mb-1"
10-
alt=""
2+
<div v-if="isAttemptingConnection">
3+
<BAlert v-if="irc.connectionStatus === 'connecting'" :model-value="true">
4+
<img
5+
src="https://s3.amazonaws.com/eterna/icon_img/loading.gif"
6+
class="loading-icon mr-auto ml-auto align-middle mb-1"
7+
alt=""
8+
/>
9+
Connecting...
10+
</BAlert>
11+
<BAlert v-else-if="irc.reconnectionStatus.isReconnecting" :model-value="true" variant="warning">
12+
<p>Connection failed. Retrying in {{ irc.reconnectionCountdown }} seconds...</p>
13+
<BProgress
14+
variant="warning"
15+
:value="irc.reconnectionCountdown"
16+
:max="irc.reconnectionStatus.retryDelay / 1_000"
17+
height="4px"
18+
></BProgress>
19+
</BAlert>
20+
<BAlert
21+
v-else-if="irc.connectionStatus === 'reconnect failed'"
22+
:model-value="true"
23+
variant="danger"
1124
>
12-
<span
13-
v-show="connectionData.tryingToConnect"
14-
id="connecting"
15-
>Connecting...</span>
16-
<span
17-
v-show="!connectionData.tryingToConnect"
18-
id="failed"
19-
>
20-
Connection failed. retrying in
21-
<span id="timer">{{ connectionData.currentTimer }}</span> seconds.
22-
</span>
23-
</li>
25+
Failed to reconnect.
26+
</BAlert>
27+
</div>
2428
</template>
2529

26-
<script lang="ts" setup>
27-
import { vxm } from '#store/vxm';
28-
import { computed } from 'vue';
30+
<script setup lang="ts">
31+
import { useIrcStore } from '#stores';
32+
import { BAlert, BProgress } from 'bootstrap-vue-next';
33+
import { computed } from 'vue';
34+
35+
const irc = useIrcStore();
2936
30-
const connectionData = computed(() => vxm.chat.connectionData);
31-
const disconnected = computed(() => vxm.chat.disconnected);
37+
const isAttemptingConnection = computed(
38+
() =>
39+
irc.connectionStatus === 'connecting' ||
40+
irc.connectionStatus === 'reconnect failed' ||
41+
irc.reconnectionStatus.isReconnecting,
42+
);
3243
</script>
3344

34-
<style lang="scss">
35-
.loading-icon {
36-
background-repeat: no-repeat;
37-
width: 20px;
38-
height: 20px;
39-
}
45+
<style scoped>
46+
.loading-icon {
47+
width: 20px;
48+
height: 20px;
49+
}
4050
</style>

src/components/connection/ConnectingPopup.vue

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/models/connection-status.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 're
22
export interface ReconnectionStatus {
33
isReconnecting: boolean;
44
retryCount: number;
5+
retryDelay: number;
56
maxRetryCount: number;
67
}

src/stores/irc.ts

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ const useIrcStore = defineStore('irc', () => {
3737
const currentNick = ref('');
3838
const isRegistered = ref(false);
3939
const connectionStatus = ref<ConnectionStatus>('disconnected');
40-
const reconnectCountdown = useCountdown(0);
41-
const reconnectStatus = reactive<ReconnectionStatus>({
40+
const reconnectionCountdown = useCountdown(0);
41+
const reconnectionStatus = reactive<ReconnectionStatus>({
4242
isReconnecting: false,
4343
retryCount: 0,
44+
retryDelay: 0,
4445
maxRetryCount: 0,
4546
});
4647

48+
/**
49+
* Creates new IRC client with a unique nick
50+
*/
4751
function initClient(username: string, uid: string) {
4852
if (client.value) {
4953
return;
@@ -62,6 +66,8 @@ const useIrcStore = defineStore('irc', () => {
6266
username: uid,
6367
gecos: username,
6468
transport: CustomConnection,
69+
auto_reconnect_max_retries: 10,
70+
auto_reconnect_max_wait: 300_000,
6571
})
6672
.on('nick in use', (event) => {
6773
// Remove used nick
@@ -80,18 +86,19 @@ const useIrcStore = defineStore('irc', () => {
8086
})
8187
.on('connected', () => {
8288
connectionStatus.value = 'connected';
83-
reconnectStatus.isReconnecting = false;
84-
reconnectCountdown.stop();
89+
reconnectionStatus.isReconnecting = false;
90+
reconnectionCountdown.stop();
8591
})
8692
.on('reconnecting', (event) => {
87-
reconnectStatus.isReconnecting = true;
88-
reconnectStatus.retryCount = event.attempt;
89-
reconnectStatus.maxRetryCount = event.max_retries;
90-
reconnectCountdown.start(event.wait / 1_000);
93+
reconnectionStatus.isReconnecting = true;
94+
reconnectionStatus.retryCount = event.attempt;
95+
reconnectionStatus.retryDelay = event.wait;
96+
reconnectionStatus.maxRetryCount = event.max_retries;
97+
reconnectionCountdown.start(event.wait / 1_000);
9198
})
9299
.on('close', () => {
93100
connectionStatus.value = 'reconnect failed';
94-
reconnectStatus.isReconnecting = false;
101+
reconnectionStatus.isReconnecting = false;
95102
})
96103
.on('debug', (message) => {
97104
log.debug(message);
@@ -120,6 +127,22 @@ const useIrcStore = defineStore('irc', () => {
120127
initClient(login.username, login.uid);
121128
}
122129

130+
/**
131+
* Manually reconnect IRC client on unexpected disconnect.
132+
* Client must first be initialized by {@link autoSignIn} or {@link signIn}
133+
*/
134+
function reconnect() {
135+
if (
136+
!isInitialized.value ||
137+
!client.value ||
138+
connectionStatus.value === 'connecting' ||
139+
connectionStatus.value === 'connected'
140+
) {
141+
return;
142+
}
143+
client.value.connect();
144+
}
145+
123146
function quit() {
124147
isRegistered.value = false;
125148
connectionStatus.value = 'disconnected';
@@ -140,12 +163,13 @@ const useIrcStore = defineStore('irc', () => {
140163
() => isRegistered.value && client.value !== null && connectionStatus.value === 'connected',
141164
),
142165
connectionStatus: readonly(connectionStatus),
143-
reconnectStatus: readonly(reconnectStatus),
144-
reconnectCountdown: readonly(reconnectCountdown.remaining),
166+
reconnectionStatus: readonly(reconnectionStatus),
167+
reconnectionCountdown: readonly(reconnectionCountdown.remaining),
145168
currentUser: readonly(currentUser),
146169
quit,
147-
autoSignIn,
148170
signIn,
171+
autoSignIn,
172+
reconnect,
149173
signOut,
150174
};
151175
});

src/stores/notifications.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const useNotificationsStore = defineStore('notifications', () => {
2121

2222
if (!isSupported) {
2323
notificationsEnabled.value = false;
24-
toast.show({
24+
toast.create({
2525
title: 'Notifications Unsupported',
2626
body: 'Your browser does not support notifications.',
2727
variant: 'warning',
@@ -40,7 +40,7 @@ const useNotificationsStore = defineStore('notifications', () => {
4040
notificationsEnabled.value = true;
4141
} else {
4242
notificationsEnabled.value = false;
43-
toast.show({
43+
toast.create({
4444
title: 'Permission Denied',
4545
body: 'Browser notifications are blocked.',
4646
variant: 'warning',

0 commit comments

Comments
 (0)