mirror of
https://github.com/open-webui/open-webui
synced 2025-06-23 02:16:52 +00:00
Merge pull request #14720 from itk-dev/feature/accessibible-chat-buttons
Feat: accessibible chat buttons
This commit is contained in:
commit
1ff7cb7d2f
@ -869,12 +869,14 @@
|
|||||||
{#if siblings.length > 1}
|
{#if siblings.length > 1}
|
||||||
<div class="flex self-center min-w-fit" dir="ltr">
|
<div class="flex self-center min-w-fit" dir="ltr">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Previous message')}
|
||||||
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
|
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
showPreviousMessage(message);
|
showPreviousMessage(message);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -940,10 +942,12 @@
|
|||||||
on:click={() => {
|
on:click={() => {
|
||||||
showNextMessage(message);
|
showNextMessage(message);
|
||||||
}}
|
}}
|
||||||
|
aria-label={$i18n.t('Next message')}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
aria-hidden="true"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
stroke-width="2.5"
|
stroke-width="2.5"
|
||||||
@ -964,6 +968,7 @@
|
|||||||
{#if $user?.role === 'user' ? ($user?.permissions?.chat?.edit ?? true) : true}
|
{#if $user?.role === 'user' ? ($user?.permissions?.chat?.edit ?? true) : true}
|
||||||
<Tooltip content={$i18n.t('Edit')} placement="bottom">
|
<Tooltip content={$i18n.t('Edit')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Edit')}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
||||||
@ -976,6 +981,7 @@
|
|||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
|
aria-hidden="true"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
@ -992,6 +998,7 @@
|
|||||||
|
|
||||||
<Tooltip content={$i18n.t('Copy')} placement="bottom">
|
<Tooltip content={$i18n.t('Copy')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Copy')}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition copy-response-button"
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition copy-response-button"
|
||||||
@ -1002,6 +1009,7 @@
|
|||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
aria-hidden="true"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
@ -1019,6 +1027,7 @@
|
|||||||
{#if $user?.role === 'admin' || ($user?.permissions?.chat?.tts ?? true)}
|
{#if $user?.role === 'admin' || ($user?.permissions?.chat?.tts ?? true)}
|
||||||
<Tooltip content={$i18n.t('Read Aloud')} placement="bottom">
|
<Tooltip content={$i18n.t('Read Aloud')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Read Aloud')}
|
||||||
id="speak-button-{message.id}"
|
id="speak-button-{message.id}"
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
@ -1034,6 +1043,7 @@
|
|||||||
class=" w-4 h-4"
|
class=" w-4 h-4"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
aria-hidden="true"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<style>
|
<style>
|
||||||
@ -1066,6 +1076,7 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
aria-hidden="true"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
@ -1081,6 +1092,7 @@
|
|||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
|
aria-hidden="true"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
@ -1099,6 +1111,7 @@
|
|||||||
{#if $config?.features.enable_image_generation && ($user?.role === 'admin' || $user?.permissions?.features?.image_generation) && !readOnly}
|
{#if $config?.features.enable_image_generation && ($user?.role === 'admin' || $user?.permissions?.features?.image_generation) && !readOnly}
|
||||||
<Tooltip content={$i18n.t('Generate Image')} placement="bottom">
|
<Tooltip content={$i18n.t('Generate Image')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Generate Image')}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
||||||
@ -1110,6 +1123,7 @@
|
|||||||
>
|
>
|
||||||
{#if generatingImage}
|
{#if generatingImage}
|
||||||
<svg
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
class=" w-4 h-4"
|
class=" w-4 h-4"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -1144,6 +1158,7 @@
|
|||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
aria-hidden="true"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
@ -1176,6 +1191,7 @@
|
|||||||
placement="bottom"
|
placement="bottom"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
aria-hidden="true"
|
||||||
class=" {isLastMessage
|
class=" {isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition whitespace-pre-wrap"
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition whitespace-pre-wrap"
|
||||||
@ -1185,6 +1201,7 @@
|
|||||||
id="info-{message.id}"
|
id="info-{message.id}"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -1206,6 +1223,7 @@
|
|||||||
{#if !$temporaryChatEnabled && ($config?.features.enable_message_rating ?? true)}
|
{#if !$temporaryChatEnabled && ($config?.features.enable_message_rating ?? true)}
|
||||||
<Tooltip content={$i18n.t('Good Response')} placement="bottom">
|
<Tooltip content={$i18n.t('Good Response')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Good Response')}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
|
||||||
@ -1224,6 +1242,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
@ -1242,6 +1261,7 @@
|
|||||||
|
|
||||||
<Tooltip content={$i18n.t('Bad Response')} placement="bottom">
|
<Tooltip content={$i18n.t('Bad Response')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Bad Response')}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
|
||||||
@ -1260,6 +1280,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
fill="none"
|
fill="none"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
@ -1280,6 +1301,7 @@
|
|||||||
{#if isLastMessage}
|
{#if isLastMessage}
|
||||||
<Tooltip content={$i18n.t('Continue Response')} placement="bottom">
|
<Tooltip content={$i18n.t('Continue Response')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t('Continue Response')}
|
||||||
type="button"
|
type="button"
|
||||||
id="continue-response-button"
|
id="continue-response-button"
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
@ -1290,6 +1312,7 @@
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
@ -1315,6 +1338,7 @@
|
|||||||
<Tooltip content={$i18n.t('Regenerate')} placement="bottom">
|
<Tooltip content={$i18n.t('Regenerate')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={$i18n.t('Regenerate')}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition regenerate-response-button"
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition regenerate-response-button"
|
||||||
@ -1340,6 +1364,7 @@
|
|||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="2.3"
|
stroke-width="2.3"
|
||||||
|
aria-hidden="true"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
@ -1356,6 +1381,7 @@
|
|||||||
<Tooltip content={$i18n.t('Delete')} placement="bottom">
|
<Tooltip content={$i18n.t('Delete')} placement="bottom">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={$i18n.t('Delete')}
|
||||||
id="delete-response-button"
|
id="delete-response-button"
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
@ -1370,6 +1396,7 @@
|
|||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
aria-hidden="true"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
@ -1387,6 +1414,7 @@
|
|||||||
<Tooltip content={action.name} placement="bottom">
|
<Tooltip content={action.name} placement="bottom">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={action.name}
|
||||||
class="{isLastMessage
|
class="{isLastMessage
|
||||||
? 'visible'
|
? 'visible'
|
||||||
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
: 'invisible group-hover:visible'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
|
||||||
|
@ -2,10 +2,8 @@
|
|||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
import { onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { marked } from 'marked';
|
|
||||||
|
|
||||||
import tippy from 'tippy.js';
|
import tippy from 'tippy.js';
|
||||||
import { roundArrow } from 'tippy.js';
|
|
||||||
|
|
||||||
export let placement = 'top';
|
export let placement = 'top';
|
||||||
export let content = `I'm a tooltip!`;
|
export let content = `I'm a tooltip!`;
|
||||||
@ -47,6 +45,6 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={tooltipElement} aria-label={DOMPurify.sanitize(content)} class={className}>
|
<div bind:this={tooltipElement} class={className}>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1380,5 +1380,7 @@
|
|||||||
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Hele dit bidrag går direkte til plugin-udvikleren; Open WebUI tager ikke nogen procentdel. Den valgte finansieringsplatform kan dog have sine egne gebyrer.",
|
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "Hele dit bidrag går direkte til plugin-udvikleren; Open WebUI tager ikke nogen procentdel. Den valgte finansieringsplatform kan dog have sine egne gebyrer.",
|
||||||
"Youtube": "Youtube",
|
"Youtube": "Youtube",
|
||||||
"Youtube Language": "Youtube sprog",
|
"Youtube Language": "Youtube sprog",
|
||||||
"Youtube Proxy URL": "Youtube Proxy URL"
|
"Youtube Proxy URL": "Youtube Proxy URL",
|
||||||
|
"Previous message": "Forrige besked",
|
||||||
|
"Next message": "Næste besked"
|
||||||
}
|
}
|
||||||
|
@ -1380,5 +1380,7 @@
|
|||||||
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "",
|
"Your entire contribution will go directly to the plugin developer; Open WebUI does not take any percentage. However, the chosen funding platform might have its own fees.": "",
|
||||||
"Youtube": "",
|
"Youtube": "",
|
||||||
"Youtube Language": "",
|
"Youtube Language": "",
|
||||||
"Youtube Proxy URL": ""
|
"Youtube Proxy URL": "",
|
||||||
|
"Previous message": "Previous message",
|
||||||
|
"Next message": "Next message"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user