smcgateway-sv 0.4.7 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,11 @@
1
1
  <script lang="ts">
2
- import { onMount, onDestroy } from 'svelte';
2
+ import { onMount, onDestroy, type Snippet } from 'svelte';
3
3
  import { recording } from './recording.svelte.js';
4
4
  import InputDatetime from './InputDatetime.svelte';
5
5
  import { colors } from './colours.js';
6
6
 
7
+ let { module = '', header }: { module?: string; header?: Snippet } = $props();
8
+
7
9
  type Segment = {
8
10
  url: string;
9
11
  start: Date;
@@ -47,33 +49,40 @@
47
49
  return segments.findIndex((s) => tMs >= s.start.getTime() && tMs < s.end.getTime());
48
50
  }
49
51
 
52
+ $effect(() => {
53
+ module;
54
+ loadSegments();
55
+ });
56
+
50
57
  async function loadSegments() {
51
58
  isLoading = true;
52
59
  error = '';
53
60
  try {
54
61
  const ret = await recording.getRecordings(windowStart, windowEnd);
55
62
  // console.log('getRecordings()', ret);
56
- segments = ret.map((r) => {
57
- let color = deviceColorMap[r.from];
58
- if (!color) {
59
- color = colors[nextColorIndex];
60
- deviceColorMap[r.from] = color;
61
- nextColorIndex++;
62
- }
63
- const startPercent = ((r.start.getTime() - windowStart.getTime()) / WINDOW_MS) * 100;
64
- const durPercent = ((r.dur * 1000) / WINDOW_MS) * 100;
65
- return {
66
- url: `/api/recordings/${r.file}`,
67
- start: r.start,
68
- end: new Date(r.start.getTime() + r.dur * 1000),
69
- from: r.from,
70
- to: r.to,
71
- startPercent,
72
- durPercent,
73
- color,
74
- style: `left:${startPercent}%; width:${durPercent}%; background-color: ${color}`
75
- };
76
- });
63
+ segments = ret
64
+ .filter((r) => module == '' || r.file.startsWith(module))
65
+ .map((r) => {
66
+ let color = deviceColorMap[r.from];
67
+ if (!color) {
68
+ color = colors[nextColorIndex];
69
+ deviceColorMap[r.from] = color;
70
+ nextColorIndex++;
71
+ }
72
+ const startPercent = ((r.start.getTime() - windowStart.getTime()) / WINDOW_MS) * 100;
73
+ const durPercent = ((r.dur * 1000) / WINDOW_MS) * 100;
74
+ return {
75
+ url: `/api/recordings/${r.file}`,
76
+ start: r.start,
77
+ end: new Date(r.start.getTime() + r.dur * 1000),
78
+ from: r.from,
79
+ to: r.to,
80
+ startPercent,
81
+ durPercent,
82
+ color,
83
+ style: `left:${startPercent}%; width:${durPercent}%; background-color: ${color}`
84
+ };
85
+ });
77
86
  } catch (e) {
78
87
  error = 'Failed to fetch audio segments';
79
88
  } finally {
@@ -189,6 +198,9 @@
189
198
  </script>
190
199
 
191
200
  <div class="player">
201
+ {#if header}
202
+ {@render header()}
203
+ {/if}
192
204
  {@render selector(shiftWindow)}
193
205
  {@render timeline()}
194
206
  {@render callInfo(activeSegment)}
@@ -328,6 +340,7 @@ cursor: {new Date(cursor).toISOString()}<br /> -->
328
340
  bottom: 0;
329
341
  border-radius: 0;
330
342
  border-right: 3px red solid;
343
+ margin-left: -1px;
331
344
  }
332
345
  .call {
333
346
  position: absolute;
@@ -1,3 +1,8 @@
1
- declare const AudioTimeLinePlayer: import("svelte").Component<Record<string, never>, {}, "">;
1
+ import { type Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ module?: string;
4
+ header?: Snippet;
5
+ };
6
+ declare const AudioTimeLinePlayer: import("svelte").Component<$$ComponentProps, {}, "">;
2
7
  type AudioTimeLinePlayer = ReturnType<typeof AudioTimeLinePlayer>;
3
8
  export default AudioTimeLinePlayer;
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import settings from './settings.svelte.js';
3
+
4
+ let {
5
+ module = $bindable(),
6
+ id = '',
7
+ class: className = '',
8
+ allName = 'All channels'
9
+ }: { module?: string; id?: string; class?: string; allName?: string } = $props();
10
+
11
+ let channels = $derived.by(() => {
12
+ let v = settings.all['channels'];
13
+ if (v) {
14
+ return Object.keys(v).map((k) => {
15
+ return { module: k, name: v[k] };
16
+ });
17
+ } else {
18
+ return [];
19
+ }
20
+ });
21
+ </script>
22
+
23
+ <select {id} class={className} bind:value={module}>
24
+ {#if allName}
25
+ <option value="">{allName}</option>
26
+ {/if}
27
+ {#each channels as c}
28
+ <option value={c.module}>{c.name}</option>
29
+ {/each}
30
+ </select>
@@ -0,0 +1,9 @@
1
+ type $$ComponentProps = {
2
+ module?: string;
3
+ id?: string;
4
+ class?: string;
5
+ allName?: string;
6
+ };
7
+ declare const SelectChannel: import("svelte").Component<$$ComponentProps, {}, "module">;
8
+ type SelectChannel = ReturnType<typeof SelectChannel>;
9
+ export default SelectChannel;
package/dist/index.d.ts CHANGED
@@ -12,5 +12,6 @@ import { recording, type Recording } from "./recording.svelte.js";
12
12
  import AudioTimeLinePlayer from "./AudioTimeLinePlayer.svelte";
13
13
  import VoicePlayer from "./VoicePlayer.svelte";
14
14
  import csv from "./csv.js";
15
- export { auth, gtime, geofence, device, ghistory, InputDate, InputDatetime, InputDebounced, InputIdentUri, LoginForm, recording, AudioTimeLinePlayer, VoicePlayer, csv, };
15
+ import settings from "./settings.svelte.js";
16
+ export { auth, gtime, geofence, device, ghistory, InputDate, InputDatetime, InputDebounced, InputIdentUri, LoginForm, recording, AudioTimeLinePlayer, VoicePlayer, csv, settings, };
16
17
  export type { User, GeoFence, Device, Log, State, Recording };
package/dist/index.js CHANGED
@@ -13,4 +13,5 @@ import { recording } from "./recording.svelte.js";
13
13
  import AudioTimeLinePlayer from "./AudioTimeLinePlayer.svelte";
14
14
  import VoicePlayer from "./VoicePlayer.svelte";
15
15
  import csv from "./csv.js";
16
- export { auth, gtime, geofence, device, ghistory, InputDate, InputDatetime, InputDebounced, InputIdentUri, LoginForm, recording, AudioTimeLinePlayer, VoicePlayer, csv, };
16
+ import settings from "./settings.svelte.js";
17
+ export { auth, gtime, geofence, device, ghistory, InputDate, InputDatetime, InputDebounced, InputIdentUri, LoginForm, recording, AudioTimeLinePlayer, VoicePlayer, csv, settings, };
@@ -0,0 +1,13 @@
1
+ declare class Settings {
2
+ private _loaded;
3
+ all: {
4
+ [key: string]: any;
5
+ };
6
+ constructor();
7
+ loaded(): Promise<boolean>;
8
+ getValue(path: string, defaultValue?: any): any;
9
+ getString(path: string, _default?: string): string;
10
+ getNumber(path: string, _default?: number): number;
11
+ }
12
+ declare const settings: Settings;
13
+ export default settings;
@@ -0,0 +1,74 @@
1
+ class Settings {
2
+ _loaded;
3
+ all = $state({});
4
+ constructor() {
5
+ let resolveLoaded;
6
+ this._loaded = new Promise((resolve) => {
7
+ resolveLoaded = resolve;
8
+ });
9
+ fetch("_settings", { signal: AbortSignal.timeout(5000) })
10
+ .then(resp => {
11
+ if (resp.status === 200) {
12
+ const regSection = /\[([a-zA-Z0-9]+)\]/;
13
+ const regKeyVal = /([a-zA-Z0-9_-]+) *= *(.*)/;
14
+ resp.text().then(t => {
15
+ try {
16
+ this.all = JSON.parse(t);
17
+ }
18
+ catch (e) {
19
+ let currentSection = "";
20
+ t.split("\n").forEach(line => {
21
+ line = line.trim();
22
+ if (!line || line.startsWith("#"))
23
+ return;
24
+ if (line.startsWith("[")) {
25
+ const m = regSection.exec(line);
26
+ if (m) {
27
+ currentSection = m[1];
28
+ this.all[currentSection] = {};
29
+ }
30
+ }
31
+ else {
32
+ const m = regKeyVal.exec(line);
33
+ if (m) {
34
+ this.all[currentSection][m[1]] = m[2];
35
+ }
36
+ }
37
+ });
38
+ }
39
+ resolveLoaded(true);
40
+ });
41
+ }
42
+ else {
43
+ resolveLoaded(true); // resolve even if non-200
44
+ }
45
+ })
46
+ .catch(() => resolveLoaded(true)); // resolve even on fetch failure
47
+ }
48
+ async loaded() {
49
+ return this._loaded;
50
+ }
51
+ getValue(path, defaultValue) {
52
+ return path.split('.').reduce((acc, key) => {
53
+ if (acc && typeof acc === 'object' && key in acc) {
54
+ return acc[key];
55
+ }
56
+ return defaultValue;
57
+ }, this.all);
58
+ }
59
+ getString(path, _default = "") {
60
+ return path.split('.').reduce((acc, key) => {
61
+ if (acc && typeof acc === 'object' && key in acc) {
62
+ return acc[key];
63
+ }
64
+ return _default;
65
+ }, this.all).toString();
66
+ }
67
+ getNumber(path, _default = 0) {
68
+ const s = this.getString(path, "");
69
+ let v = parseFloat(s);
70
+ return v || _default;
71
+ }
72
+ }
73
+ const settings = new Settings();
74
+ export default settings;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smcgateway-sv",
3
- "version": "0.4.7",
3
+ "version": "0.4.9",
4
4
  "author": "Kevin Golding <kevin.golding@smc-gateway.com> (https://smc-gateway.com)",
5
5
  "license": "MIT",
6
6
  "scripts": {