Skip to content

Commit f91dd91

Browse files
committed
feat: add an ability to switch local chat mode between text and image
1 parent a712a28 commit f91dd91

File tree

5 files changed

+182
-45
lines changed

5 files changed

+182
-45
lines changed

_build/js/src/resource.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,11 @@ const createHistoryNav = (cache: ReturnType<typeof history.init<DataContext>>) =
125125
const createFreeTextPrompt = (fieldName: string) => {
126126
const wandEl = createWandEl();
127127
wandEl.addEventListener('click', () => {
128-
ui.freePrompt({
128+
ui.localChat({
129129
key: fieldName,
130130
field: fieldName,
131131
type: 'text',
132+
availableTypes: ['text', 'image'],
132133
// @ts-ignore
133134
resource: MODx.request.id,
134135
});
@@ -184,7 +185,7 @@ const createForcedTextPrompt = (field: any, fieldName: string) => {
184185
const createImagePrompt = (mediaSource: string, fieldName: string, onSuccess: (msg: Message) => void) => {
185186
const imageWand = createWandEl();
186187
imageWand.addEventListener('click', () => {
187-
ui.freePrompt({
188+
ui.localChat({
188189
key: fieldName,
189190
field: fieldName,
190191
type: 'image',

_build/js/src/ui/actionButton.ts

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {createElement} from "./utils";
1+
import {applyStyles, createElement} from "./utils";
22
import {Message} from "../chatHistory";
33
import {Modal} from "./modal";
44

@@ -11,12 +11,19 @@ type ActionButtonConfig = {
1111
modal: Modal;
1212
completedTextDuration?: number;
1313
onClick: (msg: Message, modal: Modal) => void | Promise<void>;
14+
disabled?: boolean;
1415
}
1516

17+
export type ActionButton = HTMLButtonElement & {
18+
disable?: () => void;
19+
enable?: () => void;
20+
};
21+
1622
const defaultConfig: Partial<ActionButtonConfig> = {
1723
loadingText: 'Loading...',
1824
completedText: 'Completed!',
1925
completedTextDuration: 2000,
26+
disabled: false,
2027
};
2128

2229
const styles = {
@@ -29,7 +36,8 @@ const styles = {
2936
cursor: 'pointer',
3037
display: 'flex',
3138
alignItems: 'center',
32-
color: '#4a5568'
39+
color: '#4a5568',
40+
opacity: '1',
3341
},
3442
icon: {
3543
display: 'inline-block',
@@ -40,6 +48,10 @@ const styles = {
4048
backgroundRepeat: 'no-repeat',
4149
backgroundPosition: 'center'
4250
},
51+
disabledButton: {
52+
opacity: '0.5',
53+
cursor: 'not-allowed'
54+
},
4355
};
4456

4557
const icons = {
@@ -53,21 +65,34 @@ export const createActionButton = (config: ActionButtonConfig) => {
5365
...config,
5466
};
5567

56-
const copyBtn = createElement('button', styles.actionButton);
68+
const button = createElement('button', styles.actionButton) as ActionButton;
69+
button.className = 'action-button';
70+
button.enable = () => {
71+
button.disabled = false;
72+
applyStyles(button, styles.actionButton);
73+
}
74+
button.disable = () => {
75+
button.disabled = true;
76+
applyStyles(button, {...styles.actionButton, ...styles.disabledButton});
77+
}
78+
79+
if (config.disabled) {
80+
button.disable();
81+
}
5782

5883
const copyIcon = createElement('span', {
5984
...styles.icon,
6085
backgroundImage: `url("${icons[config.icon]}")`
6186
});
62-
copyBtn.append(copyIcon);
87+
button.append(copyIcon);
6388

64-
copyBtn.append(document.createTextNode(config.label));
65-
copyBtn.addEventListener('click', async () => {
66-
const originalHTML = copyBtn.innerHTML;
89+
button.append(document.createTextNode(config.label));
90+
button.addEventListener('click', async () => {
91+
const originalHTML = button.innerHTML;
6792
const result = config.onClick(config.message, config.modal);
6893

6994
if (result instanceof Promise) {
70-
copyBtn.innerHTML = `
95+
button.innerHTML = `
7196
<span style="
7297
display: inline-block;
7398
margin-right: 5px;
@@ -134,13 +159,13 @@ export const createActionButton = (config: ActionButtonConfig) => {
134159
document.head.removeChild(style);
135160
}
136161

137-
copyBtn.innerHTML = `
162+
button.innerHTML = `
138163
<span style="margin-right: 5px;">✓</span>
139164
${config.completedText}
140165
`;
141166
await new Promise(resolve => setTimeout(resolve, 2000));
142-
copyBtn.innerHTML = originalHTML;
167+
button.innerHTML = originalHTML;
143168
});
144169

145-
return copyBtn;
170+
return button;
146171
}

_build/js/src/ui/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { createLoadingOverlay } from './overlay'
44

55
export const ui = {
66
createLoadingOverlay,
7-
freePrompt: (config: ModalConfig) => {
7+
localChat: (config: ModalConfig) => {
88
return createModal(config);
99
}
1010
};

0 commit comments

Comments
 (0)