@dinghy-chat/widget 0.28.0 → 0.29.0

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.
package/README.md CHANGED
@@ -21,7 +21,7 @@ const dinghy = init({ url: "https://chat.example.com", key: "YOUR_PUBLIC_KEY" })
21
21
  dinghy.on("unread", (count) => console.log(count));
22
22
  ```
23
23
 
24
- `init` adds the tag once and returns the typed `Dinghy` object. Calls made before the script loads wait for it. It takes `url`, `key`, and `primary`, `accent`, `mascot`, `branding`, `launcher`, `position`, `offsetX`, `offsetY` and `zIndex`.
24
+ `init` adds the tag once and returns the typed `Dinghy` object. Calls made before the script loads wait for it. It takes `url`, `key`, and `primary`, `accent`, `mascot`, `branding`, `launcher`, `position`, `offsetX`, `offsetY`, `zIndex` and `locale`.
25
25
 
26
26
  ## Attributes
27
27
 
@@ -34,6 +34,7 @@ dinghy.on("unread", (count) => console.log(count));
34
34
  | `data-position="left"` | Puts the launcher and the chat on the left. The default is `right`. |
35
35
  | `data-offset-x="24"` | Pixels from the side of the window. The default is `16`. |
36
36
  | `data-offset-y="80"` | Pixels from the bottom of the window. The default is `16`. |
37
+ | `data-locale="fr"` | The widget's language: `en`, `fr` or `es`, over the workspace's Language setting. |
37
38
 
38
39
  The widget ignores a value in any other format. The boat stops moving for a visitor who asks for reduced motion.
39
40
 
@@ -41,17 +42,17 @@ Set `--dinghy-font`, `--dinghy-radius` and `--dinghy-launcher-radius` on the `di
41
42
 
42
43
  ## Host page API
43
44
 
44
- | Call | What it does |
45
- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------- |
46
- | `Dinghy.open({ message })` | Opens the chat. `message` is optional and fills the message box without sending it |
47
- | `Dinghy.close()`, `Dinghy.toggle()` | Closes the chat, or opens it if it is closed |
48
- | `Dinghy.show()`, `Dinghy.hide()` | Shows or hides the launcher |
49
- | `Dinghy.identify(token)` | Signs in a user. `token` is a string, or a function that returns a promise of one, so a tab can renew a token |
50
- | `Dinghy.reset()` | Ends the session in all tabs. Call this at sign-out |
51
- | `Dinghy.setContext(data)` | Unsigned facts for operators, such as a plan. Up to 20 keys, each a short string, a number, a boolean or `null` |
52
- | `Dinghy.configure(options)` | Changes `primary`, `accent`, `position`, `offsetX`, `offsetY` and `zIndex` now |
53
- | `Dinghy.on(event, callback)` | Calls `callback` on each event, and returns a function that removes it |
54
- | `Dinghy.state` | `{ ready, open, unread }` |
45
+ | Call | What it does |
46
+ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
47
+ | `Dinghy.open({ message })` | Opens the chat. `message` is optional and fills the message box without sending it |
48
+ | `Dinghy.close()`, `Dinghy.toggle()` | Closes the chat, or opens it if it is closed |
49
+ | `Dinghy.show()`, `Dinghy.hide()` | Shows or hides the launcher |
50
+ | `Dinghy.identify(token)` | Signs in a user. `token` is a string, or a function that returns a promise of one, so a tab can renew a token |
51
+ | `Dinghy.reset()` | Ends the session in all tabs. Call this at sign-out |
52
+ | `Dinghy.setContext(data)` | Unsigned facts for operators, such as a plan. Up to 20 keys, each a short string, a number, a boolean or `null` |
53
+ | `Dinghy.configure(options)` | Changes `primary`, `accent`, `position`, `offsetX`, `offsetY` and `zIndex` now, and `locale` before the chat opens |
54
+ | `Dinghy.on(event, callback)` | Calls `callback` on each event, and returns a function that removes it |
55
+ | `Dinghy.state` | `{ ready, open, unread }` |
55
56
 
56
57
  The events are `ready`, `open`, `close`, `unread` (the count, at once and on each change), `message:sent` and `message:received` (`{ body }`) and `conversation:started`.
57
58
 
@@ -75,7 +76,7 @@ connect-src https://chat.example.com;
75
76
  img-src https://chat.example.com;
76
77
  ```
77
78
 
78
- If your Dinghy serves images from a separate origin (`IMAGES_ORIGIN`), allow that origin in `img-src` too.
79
+ If your Dinghy serves images and files from a separate origin (`UPLOADS_ORIGIN`), allow that origin in `img-src` and `connect-src` too, as the chat fetches a file to save it.
79
80
 
80
81
  The widget needs no `style-src` change, because it uses constructable stylesheets and the CSSOM.
81
82
 
package/dist/index.js CHANGED
@@ -60,7 +60,8 @@ function init(options) {
60
60
  ["offset-y", options.offsetY],
61
61
  ["mascot", options.mascot === void 0 ? void 0 : String(options.mascot)],
62
62
  ["branding", options.branding === void 0 ? void 0 : String(options.branding)],
63
- ["launcher", options.launcher === false ? "hidden" : void 0]
63
+ ["launcher", options.launcher === false ? "hidden" : void 0],
64
+ ["locale", options.locale]
64
65
  ];
65
66
  for (const [name, value] of attributes) {
66
67
  if (value !== void 0) script.setAttribute(`data-${name}`, String(value));
package/dist/shared.d.ts CHANGED
@@ -6,6 +6,12 @@ export interface OpenOptions {
6
6
  /** Fills the message box. The visitor still sends it. */
7
7
  message?: string;
8
8
  }
9
+ /**
10
+ * The languages the widget speaks. English is in the chat bundle, and each other one is a file
11
+ * beside it.
12
+ */
13
+ export declare const LOCALES: readonly ["en", "fr", "es"];
14
+ export type Locale = (typeof LOCALES)[number];
9
15
  /** What `configure` and the script tag's data attributes change. Invalid values are ignored. */
10
16
  export interface Appearance {
11
17
  /** A six-digit hex color, such as `#0b2239`. */
@@ -16,6 +22,8 @@ export interface Appearance {
16
22
  offsetX?: number;
17
23
  offsetY?: number;
18
24
  zIndex?: number;
25
+ /** A language the widget speaks, such as `fr`, over the saved one. Set it before the chat opens. */
26
+ locale?: string;
19
27
  }
20
28
  /** What an owner saves in the operator app's Widget tab. Null texts and colors mean the widget's own. */
21
29
  export interface WidgetSettings {
@@ -39,6 +47,8 @@ export interface WidgetSettings {
39
47
  sound: boolean;
40
48
  /** The visitor gets the conversation by email when it closes. The widget does not use it. */
41
49
  transcript: boolean;
50
+ /** Visitors may send files as well as images. */
51
+ visitorFiles: boolean;
42
52
  /** Whose faces the header shows. `online` falls back to the latest repliers when nobody is. */
43
53
  headerFaces: "online" | "repliers" | "chosen" | "none";
44
54
  /** How many faces, 1 to HEADER_FACES_MAX. */
@@ -47,6 +57,11 @@ export interface WidgetSettings {
47
57
  headerDot: boolean;
48
58
  /** Under the title while someone is online: "Online", or the usual reply time. */
49
59
  headerStatus: "presence" | "reply_time";
60
+ /**
61
+ * The widget's own words in one language, or `visitor` for the first of the browser's languages
62
+ * that the widget speaks. The team's own texts stay as written.
63
+ */
64
+ language: "visitor" | Locale;
50
65
  }
51
66
  /** A member the widget's header shows: a first name and a picture, never an email. */
52
67
  export interface TeamFace {
@@ -56,6 +71,19 @@ export interface TeamFace {
56
71
  name: string;
57
72
  pictureUrl: string | null;
58
73
  }
74
+ /** The days of the week, in the order the settings list them. */
75
+ export declare const WEEKDAYS: readonly ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
76
+ export type Weekday = (typeof WEEKDAYS)[number];
77
+ /** The most opening ranges one day holds. */
78
+ export declare const DAY_RANGES_MAX = 3;
79
+ /**
80
+ * When the team answers: each day's ranges, such as `["09:00", "18:00"]`, in order and apart, in
81
+ * the workspace's IANA time zone. A range may end at "24:00". A day with none is closed.
82
+ */
83
+ export interface BusinessHours {
84
+ timeZone: string;
85
+ week: Record<Weekday, [string, string][]>;
86
+ }
59
87
  /** The saved settings, as the widget's appearance route answers them. */
60
88
  export interface SavedAppearance extends WidgetSettings {
61
89
  /** The chat sends the visitor's unsent words, so operators see them as they type. */
@@ -68,6 +96,8 @@ export interface SavedAppearance extends WidgetSettings {
68
96
  * members online now, the latest repliers for `repliers`, the chosen members for `chosen`.
69
97
  */
70
98
  faces: TeamFace[];
99
+ /** Null while business hours are off, so the widget follows presence alone. */
100
+ hours: BusinessHours | null;
71
101
  }
72
102
  /** The longest title an owner can save. */
73
103
  export declare const TITLE_MAX = 40;
@@ -173,7 +203,10 @@ export interface WidgetContext {
173
203
  shadow: ShadowRoot;
174
204
  /** The saved settings, which the loader asked for. See loadAppearance. */
175
205
  appearance: Promise<SavedAppearance | null | undefined>;
176
- /** Reads the tag's data attributes by dataset name, such as `mascot`. They win over the saved settings. */
206
+ /**
207
+ * Reads the tag's data attributes by dataset name, such as `mascot`, and the values configure()
208
+ * set. They win over the saved settings.
209
+ */
177
210
  attribute(name: string): string | undefined;
178
211
  /** The full-page chat that a reply email opens, on the Dinghy server's own origin. */
179
212
  page?: boolean;
@@ -206,6 +239,39 @@ export declare function rememberOpen(publicKey: string, open: boolean): void;
206
239
  export declare function forgetVisitor(publicKey: string): void;
207
240
  /** The longest message, in characters: the composers' limit, which the server checks too. */
208
241
  export declare const MESSAGE_MAX = 10000;
242
+ /** The most members one note mentions, which the operator app keeps to and the server checks. */
243
+ export declare const MENTIONS_MAX = 10;
244
+ /** The longest saved reply shortcut, in characters, where the form's field stops. */
245
+ export declare const SAVED_REPLY_SHORTCUT_MAX = 32;
246
+ /**
247
+ * A saved reply's shortcut, what follows `/` in the composer. The form, the server and the database
248
+ * check it.
249
+ */
250
+ export declare const SAVED_REPLY_SHORTCUT: RegExp;
251
+ /**
252
+ * The limits of saved replies, labels and bulk changes. The server and the database check them, and
253
+ * the operator app keeps to them and names them in its texts.
254
+ */
255
+ export declare const SAVED_REPLIES_MAX = 200;
256
+ export declare const SAVED_REPLY_BODY_MAX = 5000;
257
+ export declare const LABELS_MAX = 100;
258
+ export declare const LABEL_NAME_MAX = 40;
259
+ /** The most conversations one bulk change takes. */
260
+ export declare const BULK_MAX = 100;
261
+ /**
262
+ * The longest two-step sign-in code the server takes once spaces are gone, well above a recovery
263
+ * code's 19 characters with its dashes. The operator app's field stops there, so a code typed with
264
+ * spaces always fits.
265
+ */
266
+ export declare const TWO_FACTOR_CODE_MAX = 40;
267
+ /**
268
+ * The rules of a request to remove two-step sign-in, which the server applies and the operator app
269
+ * names: the wait before it completes, how long a cancel blocks a new request, and how recent the
270
+ * email link of the session that asks must be.
271
+ */
272
+ export declare const TWO_FACTOR_REMOVAL_WAIT_HOURS = 72;
273
+ export declare const TWO_FACTOR_REMOVAL_BLOCK_DAYS = 7;
274
+ export declare const TWO_FACTOR_REMOVAL_FRESH_MINUTES = 15;
209
275
  /**
210
276
  * A bot repeats its typing notice while it writes, so one that stops repeating has stopped: the
211
277
  * chat and the operator app drop it after this long with no update.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dinghy-chat/widget",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "Add the Dinghy chat to your site from code, with a typed API.",
5
5
  "type": "module",
6
6
  "license": "MIT",