Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
bbfa54a6
Commit
bbfa54a6
authored
Jun 04, 2024
by
Timothy J. Baek
Browse files
feat: active user count
parent
4925a653
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
50 additions
and
17 deletions
+50
-17
backend/apps/socket/main.py
backend/apps/socket/main.py
+15
-12
src/lib/components/layout/Sidebar/UserMenu.svelte
src/lib/components/layout/Sidebar/UserMenu.svelte
+27
-3
src/lib/stores/index.ts
src/lib/stores/index.ts
+1
-0
src/routes/+layout.svelte
src/routes/+layout.svelte
+7
-2
No files found.
backend/apps/socket/main.py
View file @
bbfa54a6
...
@@ -7,6 +7,8 @@ sio = socketio.AsyncServer(cors_allowed_origins=[], async_mode="asgi")
...
@@ -7,6 +7,8 @@ sio = socketio.AsyncServer(cors_allowed_origins=[], async_mode="asgi")
app
=
socketio
.
ASGIApp
(
sio
,
socketio_path
=
"/ws/socket.io"
)
app
=
socketio
.
ASGIApp
(
sio
,
socketio_path
=
"/ws/socket.io"
)
# Dictionary to maintain the user pool
# Dictionary to maintain the user pool
USER_POOL
=
{}
USER_POOL
=
{}
...
@@ -22,24 +24,25 @@ async def connect(sid, environ, auth):
...
@@ -22,24 +24,25 @@ async def connect(sid, environ, auth):
user
=
Users
.
get_user_by_id
(
data
[
"id"
])
user
=
Users
.
get_user_by_id
(
data
[
"id"
])
if
user
:
if
user
:
USER_POOL
[
sid
]
=
{
USER_POOL
[
sid
]
=
user
.
id
"id"
:
user
.
id
,
"name"
:
user
.
name
,
"email"
:
user
.
email
,
"role"
:
user
.
role
,
}
print
(
f
"user
{
user
.
name
}
(
{
user
.
id
}
) connected with session ID
{
sid
}
"
)
print
(
f
"user
{
user
.
name
}
(
{
user
.
id
}
) connected with session ID
{
sid
}
"
)
print
(
len
(
set
(
USER_POOL
)))
await
sio
.
emit
(
"user-count"
,
{
"count"
:
len
(
set
(
USER_POOL
))})
@
sio
.
on
(
"user-count"
)
async
def
user_count
(
sid
):
print
(
"user-count"
,
sid
)
await
sio
.
emit
(
"user-count"
,
{
"count"
:
len
(
set
(
USER_POOL
))})
@
sio
.
event
@
sio
.
event
def
disconnect
(
sid
):
async
def
disconnect
(
sid
):
if
sid
in
USER_POOL
:
if
sid
in
USER_POOL
:
disconnected_user
=
USER_POOL
.
pop
(
sid
)
disconnected_user
=
USER_POOL
.
pop
(
sid
)
print
(
f
"user
{
disconnected_user
}
disconnected with session ID
{
sid
}
"
)
print
(
f
"user
{
disconnected_user
}
disconnected with session ID
{
sid
}
"
)
await
sio
.
emit
(
"user-count"
,
{
"count"
:
len
(
USER_POOL
)})
else
:
else
:
print
(
f
"Unknown session ID
{
sid
}
disconnected"
)
print
(
f
"Unknown session ID
{
sid
}
disconnected"
)
@
sio
.
event
def
disconnect
(
sid
):
print
(
"disconnect"
,
sid
)
src/lib/components/layout/Sidebar/UserMenu.svelte
View file @
bbfa54a6
<script lang="ts">
<script lang="ts">
import { DropdownMenu } from 'bits-ui';
import { DropdownMenu } from 'bits-ui';
import { createEventDispatcher, getContext } from 'svelte';
import { createEventDispatcher, getContext
, onMount
} from 'svelte';
import { flyAndScale } from '$lib/utils/transitions';
import { flyAndScale } from '$lib/utils/transitions';
import { goto } from '$app/navigation';
import { goto } from '$app/navigation';
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
import ArchiveBox from '$lib/components/icons/ArchiveBox.svelte';
import { showSettings } from '$lib/stores';
import { showSettings
, activeUserCount
} from '$lib/stores';
import { fade, slide } from 'svelte/transition';
import { fade, slide } from 'svelte/transition';
const i18n = getContext('i18n');
const i18n = getContext('i18n');
...
@@ -107,7 +107,7 @@
...
@@ -107,7 +107,7 @@
</button>
</button>
{/if}
{/if}
<hr class=" dark:border-gray-800 my-
2
p-0" />
<hr class=" dark:border-gray-800 my-
1.5
p-0" />
<button
<button
class="flex rounded-md py-2 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition"
class="flex rounded-md py-2 px-3 w-full hover:bg-gray-50 dark:hover:bg-gray-800 transition"
...
@@ -139,6 +139,30 @@
...
@@ -139,6 +139,30 @@
<div class=" self-center font-medium">{$i18n.t('Sign Out')}</div>
<div class=" self-center font-medium">{$i18n.t('Sign Out')}</div>
</button>
</button>
{#if $activeUserCount}
<hr class=" dark:border-gray-800 my-1.5 p-0" />
<div class="flex rounded-md py-1.5 px-3 text-xs gap-2.5 items-center">
<div class=" flex items-center">
<span class="relative flex size-2">
<span
class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
/>
<span class="relative inline-flex rounded-full size-2 bg-green-500" />
</span>
</div>
<div class=" translate-y-[0.25px]">
<span class=" font-medium">
{$i18n.t('Active Users')}:
</span>
<span class=" font-semibold">
{$activeUserCount}
</span>
</div>
</div>
{/if}
<!-- <DropdownMenu.Item class="flex items-center px-3 py-2 text-sm font-medium">
<!-- <DropdownMenu.Item class="flex items-center px-3 py-2 text-sm font-medium">
<div class="flex items-center">Profile</div>
<div class="flex items-center">Profile</div>
</DropdownMenu.Item> -->
</DropdownMenu.Item> -->
...
...
src/lib/stores/index.ts
View file @
bbfa54a6
...
@@ -15,6 +15,7 @@ export const MODEL_DOWNLOAD_POOL = writable({});
...
@@ -15,6 +15,7 @@ export const MODEL_DOWNLOAD_POOL = writable({});
export
const
mobile
=
writable
(
false
);
export
const
mobile
=
writable
(
false
);
export
const
socket
:
Writable
<
null
|
Socket
>
=
writable
(
null
);
export
const
socket
:
Writable
<
null
|
Socket
>
=
writable
(
null
);
export
const
activeUserCount
:
Writable
<
null
|
number
>
=
writable
(
null
);
export
const
theme
=
writable
(
'
system
'
);
export
const
theme
=
writable
(
'
system
'
);
export
const
chatId
=
writable
(
''
);
export
const
chatId
=
writable
(
''
);
...
...
src/routes/+layout.svelte
View file @
bbfa54a6
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
import { io } from 'socket.io-client';
import { io } from 'socket.io-client';
import { onMount, tick, setContext } from 'svelte';
import { onMount, tick, setContext } from 'svelte';
import { config, user, theme, WEBUI_NAME, mobile, socket } from '$lib/stores';
import { config, user, theme, WEBUI_NAME, mobile, socket
, activeUserCount
} from '$lib/stores';
import { goto } from '$app/navigation';
import { goto } from '$app/navigation';
import { Toaster, toast } from 'svelte-sonner';
import { Toaster, toast } from 'svelte-sonner';
...
@@ -69,7 +69,12 @@
...
@@ -69,7 +69,12 @@
console.log('connected');
console.log('connected');
});
});
socket.set(_socket);
await socket.set(_socket);
_socket.on('user-count', (data) => {
console.log('user-count', data);
activeUserCount.set(data.count);
});
if (localStorage.token) {
if (localStorage.token) {
// Get Session User Info
// Get Session User Info
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment