File size: 3,216 Bytes
0bd62e5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script lang="ts">

	import LikeDislike from "./LikeDislike.svelte";

	import Copy from "./Copy.svelte";

	import type { FileData } from "@gradio/client";

	import DownloadIcon from "./Download.svelte";

	import { DownloadLink } from "@gradio/wasm/svelte";

	import type { NormalisedMessage, TextMessage } from "../types";

	import { is_component_message } from "./utils";



	export let likeable: boolean;

	export let show_copy_button: boolean;

	export let show: boolean;

	export let message: NormalisedMessage | NormalisedMessage[];

	export let position: "right" | "left";

	export let avatar: FileData | null;



	export let handle_action: (selected: string | null) => void;

	export let layout: "bubble" | "panel";



	function is_all_text(

		message: NormalisedMessage[] | NormalisedMessage

	): message is TextMessage[] | TextMessage {

		return (

			(Array.isArray(message) &&

				message.every((m) => typeof m.content === "string")) ||

			(!Array.isArray(message) && typeof message.content === "string")

		);

	}



	function all_text(message: TextMessage[] | TextMessage): string {

		if (Array.isArray(message)) {

			return message.map((m) => m.content).join("\n");

		}

		return message.content;

	}



	$: message_text = is_all_text(message) ? all_text(message) : "";



	$: show_copy = show_copy_button && message && is_all_text(message);

	$: show_download =

		!Array.isArray(message) &&

		is_component_message(message) &&

		message.content.value?.url;

</script>

{#if show}
	<div

		class="message-buttons-{position} {layout}  message-buttons {avatar !==

			null && 'with-avatar'}"

	>
		{#if show_copy}
			<Copy value={message_text} />
		{/if}
		{#if show_download && !Array.isArray(message) && is_component_message(message)}
			<DownloadLink

				href={message?.content?.value.url}

				download={message.content.value.orig_name || "image"}

			>
				<span class="icon-wrap">
					<DownloadIcon />
				</span>
			</DownloadLink>
		{/if}
		{#if likeable}
			<LikeDislike {handle_action} padded={show_copy || show_download} />
		{/if}
	</div>
{/if}

<style>

	.icon-wrap {

		display: block;

		color: var(--body-text-color-subdued);

	}



	.icon-wrap:hover {

		color: var(--body-text-color);

	}



	.message-buttons {

		border-radius: var(--radius-md);

		display: flex;

		align-items: center;



		height: var(--size-7);

		align-self: self-end;

		margin: 0px calc(var(--spacing-xl) * 3);

		padding-left: 5px;

		z-index: 1;

		padding-bottom: var(--spacing-xl);

		padding: var(--spacing-md) var(--spacing-md);

		border: 1px solid var(--border-color-primary);

		background: var(--border-color-secondary);

		gap: var(--spacing-md);

	}

	.message-buttons-left {

		align-self: start;

		left: 0px;

	}



	.panel.message-buttons-left,

	.panel.message-buttons-right {

		margin: 10px 0 2px 0;

	}



	/* .message-buttons {

		left: 0px;

		right: 0px;

		top: unset;

		bottom: calc(-30px - var(--spacing-xl));

		display: flex;

		justify-content: flex-start;

		align-items: center;

		gap: 0px;

	} */



	.message-buttons :global(> *) {

		margin-right: 0px;

	}



	.with-avatar {

		margin-left: calc(var(--spacing-xl) * 4 + 31px);

	}

</style>