jdelavande HF Staff commited on
Commit
0921221
·
1 Parent(s): 0897191

add equivalents

Browse files
src/lib/components/chat/ChatWindow.svelte CHANGED
@@ -32,6 +32,7 @@
32
  import UploadedFile from "./UploadedFile.svelte";
33
  import { useSettingsStore } from "$lib/stores/settings";
34
  import ModelSwitch from "./ModelSwitch.svelte";
 
35
 
36
  import { fly } from "svelte/transition";
37
  import { cubicInOut } from "svelte/easing";
@@ -350,21 +351,7 @@
350
  scrollNode={chatContainer}
351
  />
352
  </div>
353
- <div
354
- class="dark:via-gray-80 pointer-events-none absolute inset-x-0 bottom-0 z-0 mx-auto flex w-full max-w-3xl flex-col items-center justify-center bg-gradient-to-t from-white via-white/80 to-white/0 px-3.5 py-4 dark:border-gray-800 dark:from-gray-900 dark:to-gray-900/0 max-md:border-t max-md:bg-white max-md:dark:bg-gray-900 sm:px-5 md:py-8 xl:max-w-4xl [&>*]:pointer-events-auto"
355
- >
356
- {#if messages.length > 0}
357
- {@const totalEnergy = messages.reduce((total, msg) => total + (msg.metadata?.energy_wh || msg.metadata?.energy_wh_sim || 0), 0)}
358
- {@const isNotEstimated = typeof messages.at(-1)?.metadata?.energy_wh === "number" && messages.at(-1).metadata.energy_wh !== 0}
359
- {#if totalEnergy > 0}
360
- <div class="mb-4 flex items-center justify-center">
361
- <div class="text-xs text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded">
362
- Total Energy: {totalEnergy.toFixed(4)} Wh {#if !isNotEstimated} (estimated) {/if}
363
- (about {((totalEnergy / 19) * 100).toFixed(2)}% of charging a phone)
364
- </div>
365
- </div>
366
- {/if}
367
- {/if}
368
 
369
  {#if sources?.length && !loading}
370
  <div
@@ -384,6 +371,12 @@
384
  </div>
385
  {/if}
386
 
 
 
 
 
 
 
387
  <div class="w-full">
388
  <div class="flex w-full *:mb-3">
389
  {#if loading}
 
32
  import UploadedFile from "./UploadedFile.svelte";
33
  import { useSettingsStore } from "$lib/stores/settings";
34
  import ModelSwitch from "./ModelSwitch.svelte";
35
+ import EnergySummary from "./EnergySummary.svelte";
36
 
37
  import { fly } from "svelte/transition";
38
  import { cubicInOut } from "svelte/easing";
 
351
  scrollNode={chatContainer}
352
  />
353
  </div>
354
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
 
356
  {#if sources?.length && !loading}
357
  <div
 
371
  </div>
372
  {/if}
373
 
374
+ <div
375
+ class="dark:via-gray-80 pointer-events-none absolute inset-x-0 bottom-0 z-0 mx-auto flex w-full max-w-3xl flex-col items-center justify-center bg-gradient-to-t from-white via-white/80 to-white/0 px-3.5 py-4 dark:border-gray-800 dark:from-gray-900 dark:to-gray-900/0 max-md:border-t max-md:bg-white max-md:dark:bg-gray-900 sm:px-5 md:py-8 xl:max-w-4xl [&>*]:pointer-events-auto"
376
+ >
377
+ <EnergySummary {messages} />
378
+
379
+
380
  <div class="w-full">
381
  <div class="flex w-full *:mb-3">
382
  {#if loading}
src/lib/components/chat/EnergySummary.svelte ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ let { messages } = $props();
3
+
4
+ const totalEnergy = $derived(messages.reduce(
5
+ (total: number, msg: any) => total + (msg.metadata?.energy_wh || msg.metadata?.energy_wh_sim || 0),
6
+ 0
7
+ ));
8
+
9
+ const isNotEstimated = $derived(
10
+ typeof messages.at(-1)?.metadata?.energy_wh === 'number' &&
11
+ messages.at(-1).metadata.energy_wh !== 0);
12
+
13
+ const phoneChargePercent = $derived(((totalEnergy / 19) * 100).toFixed(2));
14
+
15
+ let showJoules = $state(false);
16
+ let equivalentIndex = $state(0);
17
+
18
+ const equivalents = [
19
+ (wh: number) => `≈ ${((wh / 19) * 100).toFixed(2)}% of a phone charge (19Wh)`,
20
+ (wh: number) => `≈ ${(wh / 0.04).toFixed(2)} minutes of LED bulb (10W)`, // 0.04Wh/min
21
+ (wh: number) => `≈ ${(wh / 1.5).toFixed(2)} seconds of microwave (1000W)`,
22
+ (wh: number) => `≈ ${(wh / 0.2).toFixed(2)} pedal strokes on an e-bike (200W)`,
23
+ (wh: number) => `≈ ${(wh / 12).toFixed(2)} seconds of toaster use (1kW)`
24
+ ];
25
+
26
+ function cycleEquivalent() {
27
+ equivalentIndex = (equivalentIndex + 1) % equivalents.length;
28
+ }
29
+
30
+ function convertToJoules(wh: number): number {
31
+ return wh * 3600;
32
+ }
33
+ </script>
34
+
35
+ {#if totalEnergy > 0}
36
+ <div class="mb-4 flex flex-col sm:flex-row flex-wrap items-center justify-center gap-4 w-full">
37
+ <!-- Bloc énergie totale -->
38
+ <div class="text-xs text-gray-500 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded transform hover:scale-105 transition duration-150 ease-in-out cursor-pointer" on:click={() => (showJoules = !showJoules)}>
39
+ Total Energy:
40
+ {#if showJoules}
41
+ {convertToJoules(totalEnergy).toFixed(2)} J
42
+ {:else}
43
+ {totalEnergy.toFixed(4)} Wh
44
+ {/if}
45
+ {#if !isNotEstimated} (estimated) {/if}
46
+ </div>
47
+
48
+ <!-- Bloc équivalent charge téléphone -->
49
+ <div class="text-xs text-gray-500 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 px-3 py-1 rounded cursor-pointer transform hover:scale-105 transition duration-150 ease-in-out" on:click={cycleEquivalent}>
50
+ {equivalents[equivalentIndex](totalEnergy)}
51
+ </div>
52
+ </div>
53
+ {/if}