Skip to content

Commit d648f53

Browse files
authored
Merge branch 'main' into feature/show-tooltip-on-focus
2 parents 99e9647 + f0df996 commit d648f53

File tree

6 files changed

+95
-35
lines changed

6 files changed

+95
-35
lines changed

docs/resources/control-flow/user-interactivity/forms/form-widgets/text-field.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,15 @@ To autofocus a TextField, select the TextField widget, move to the **Properties
410410
</div>
411411
<p></p>
412412

413+
### Enable Interactive Selection
414+
415+
The **Enable Interactive Selection** toggle controls whether users can interact with the text selection features, such as long-press selection, copy/paste menus, and selection handles.
416+
417+
By default, this property is set to **True**, allowing users to select, copy, and paste text using the platform's built-in text selection controls. Disabling this can help prevent unintended text copying or editing, especially in sensitive fields.
418+
419+
420+
![interactive-selection](../imgs/interactive-selection.avif)
421+
413422
### Autocomplete a TextField
414423

415424
You might want to allow users to enter the text by suggesting them a list of items. The suggested items are shown if it contains the currently entered text from TextField. For example, using autocomplete to get the *Country* *name*, *Fruit* *name*, etc.
Binary file not shown.

docs/resources/projects/libraries.md

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,17 +253,17 @@ You can easily upgrade to newer versions of the libraries as they become availab
253253

254254
## Library Pages
255255

256-
You can also add and manage pages within a library, making it easy to reuse those pages across multiple projects. These pages function like any regular project page in your app; they support navigation, parameters, state management, and transitions.
256+
When you publish a library, all the pages included in the library become available for use in the consumer project. These pages function like any regular project page in your app; they support navigation, parameters, state management, and transitions.
257257

258-
Including pages with libraries offers a modular approach to development, making it ideal for large teams and complex, multi-feature apps. For example, instead of recreating common flows like onboarding and payment flows, you can build them in a library once and use them wherever needed.
258+
Library Pages offers a modular approach to development, making it ideal for large teams and complex, multi-feature apps. For example, instead of recreating common flows like onboarding and payment flows, you can build them in a library once and use them wherever needed.
259259

260260
:::tip[Possible Use Cases]
261261
- **Super Apps** like Gojek and Uber with distinct modules such as ride booking, shopping, and payments. Each module can be developed as a separate library and imported into a single main project.
262262
- **Enterprise Apps** with isolated user journeys for different roles, such as admin and customer. Each role-based flow can be built as its own library and integrated into the core app as needed.
263263
- **White-labeled Apps** that share common onboarding flows can benefit from libraries. The onboarding process can be built once as a library and reused across all branded versions of the app.
264264
:::
265265

266-
The library author selects which pages to include and publishes the library. When users import or update the library, they can override the default route names to prevent conflicts between the library and their project. Library pages then appear in navigation actions just like any regular page.
266+
When users import or update the library, they can override the default route names to prevent conflicts between the library and their project. Library pages then appear in navigation actions just like any regular page.
267267

268268
<div style={{
269269
position: 'relative',
@@ -291,7 +291,50 @@ The library author selects which pages to include and publishes the library. Whe
291291
</div>
292292
<p></p>
293293

294+
### Library Pages in NavBar
294295

296+
Library pages can also be used in the NavBar, allowing users to add reusable flows into the app’s primary navigation structure. For example, in a Super App, you can import ride booking, food delivery, or payment pages from separate libraries and add them directly to the bottom navigation, giving users quick access to each module.
297+
298+
:::tip
299+
Want to learn more about building modular Super Apps using libraries? Check out our [**blog post**](https://blog.flutterflow.io/scaling-super-apps-modular-architecture-with-flutterflow-libraries/).
300+
:::
301+
302+
To display a library page on the NavBar, navigate to **Project Dependencies > FlutterFlow Libraries**, then click on **Pages** for the relevant library to open its details. In the list of pages, locate the desired page and click **Nav Bar Settings**, then enable **Show on NavBar**. You can also customize additional settings, such as label and icon, as needed.
303+
304+
To confirm, go to the **Nav Bar & App Bar** section, where you’ll see the library page listed as part of the NavBar items.
305+
306+
:::info
307+
NavBar settings for regular pages are available directly within the Page Settings panel in the builder. However, for Library pages, these settings are managed through the Library Details dialog.
308+
309+
![NavBar-settings-for-regular-and-library-page](imgs/NavBar-settings-for-regular-and-library-page.avif)
310+
:::
311+
312+
313+
<div style={{
314+
position: 'relative',
315+
paddingBottom: 'calc(56.67989417989418% + 41px)', // Keeps the aspect ratio and additional padding
316+
height: 0,
317+
width: '100%'}}>
318+
<iframe
319+
src="https://demo.arcade.software/BDac382RQTHTKFhtZcsc?embed&show_copy_link=true"
320+
title=""
321+
style={{
322+
position: 'absolute',
323+
top: 0,
324+
left: 0,
325+
width: '100%',
326+
height: '100%',
327+
colorScheme: 'light'
328+
}}
329+
frameborder="0"
330+
loading="lazy"
331+
webkitAllowFullScreen
332+
mozAllowFullScreen
333+
allowFullScreen
334+
allow="clipboard-write">
335+
</iframe>
336+
</div>
337+
<p></p>
295338

296339
## Library Values
297340

docs/resources/projects/settings/project-apis.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ Authorization: Bearer YOUR_API_TOKEN_HERE
103103
## API Endpoints
104104
Below is a list of available API endpoints with their methods and usage descriptions.
105105

106-
| Endpoint | Method | Purpose |
107-
| --------------------------- | ------ | --------------------------------------------- |
108-
| `/listPartitionedFileNames` | GET | List available YAML file names for a project. |
109-
| `/l/listProjects` | POST | Retrieve metadata for all projects. |
110-
| `/projectYamls` | GET | Export/download YAML files from a project. |
111-
| `/validateProjectYaml` | POST | Validate YAML content before applying changes. |
112-
| `/updateProjectYaml` | POST | Update project configuration via YAML. |
106+
| Endpoint | Method | Purpose |
107+
| --------------------------- | ------ | --------------------------------------------- |
108+
| `/listPartitionedFileNames` | GET | List available YAML file names for a project. |
109+
| `/l/listProjects` | POST | Retrieve metadata for all projects. |
110+
| `/projectYamls` | GET | Export/download YAML files from a project. |
111+
| `/validateProjectYaml` | POST | Validate YAML content before applying changes. |
112+
| `/updateProjectByYaml` | POST | Update project configuration via YAML. |
113113

114114

115115
### List File Names
@@ -358,7 +358,7 @@ curl -X POST \
358358
This endpoint allows you to overwrite existing files in your FlutterFlow project by submitting updated YAML content.
359359

360360
#### Endpoint
361-
`POST /updateProjectYaml`
361+
`POST /updateProjectByYaml`
362362

363363
#### Request Body
364364
```jsx
@@ -413,7 +413,7 @@ This example updates the `ad-mob` file and adds/updates app state variables.
413413

414414
```jsx
415415
curl -X POST \
416-
'https://api.flutterflow.io/v2/updateProjectYaml' \
416+
'https://api.flutterflow.io/v2/updateProjectByYaml' \
417417
-H 'Authorization: Bearer YOUR_API_TOKEN' \
418418
-H 'Content-Type: application/json' \
419419
-d '{
@@ -462,7 +462,7 @@ First, we use the `/listPartitionedFileNames` endpoint to check if the `app-stat
462462
</div>
463463
<p></p>
464464

465-
Next, we open the `app-state.yaml` file and update the `enableDarkMode` variable by setting its `persisted` value to `true`. We then convert the updated YAML into a properly escaped single line string and validate it using the `/validateProjectYaml` endpoint. If validation succeeds, we send the final update using the `/updateProjectYaml` endpoint.
465+
Next, we open the `app-state.yaml` file and update the `enableDarkMode` variable by setting its `persisted` value to `true`. We then convert the updated YAML into a properly escaped single line string and validate it using the `/validateProjectYaml` endpoint. If validation succeeds, we send the final update using the `/updateProjectByYaml` endpoint.
466466

467467

468468
<div style={{
@@ -535,7 +535,7 @@ When YAML validation fails, you'll receive detailed error information:
535535
-d '{"projectId": "project-id", "fileKey": "ad-mob", "fileContent": "showTestAds: false"}'
536536
537537
# 2. If validation passes, apply the changes
538-
curl -X POST 'https://api.flutterflow.io/v2/updateProjectYaml' \
538+
curl -X POST 'https://api.flutterflow.io/v2/updateProjectByYaml' \
539539
-H 'Authorization: Bearer YOUR_API_KEY' \
540540
-H 'Content-Type: application/json' \
541541
-d '{"projectId": "project-id", "fileKeyToContent": {"ad-mob": "showTestAds: false"}}'

src/js/chatbot.js

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
(function() {
33
if (typeof window === 'undefined') return;
44

5+
// TEMPORARY DISABLE FLAG - Set to false to disable chatbot
6+
const CHATBOT_ENABLED = false;
7+
8+
if (!CHATBOT_ENABLED) {
9+
console.log('Chatbot is temporarily disabled');
10+
return;
11+
}
12+
513
// Set configuration
614
window.difyChatbotConfig = {
715
token: 'bYIppJMzMieMPDHm'
@@ -64,12 +72,13 @@
6472

6573
// Function to force positioning
6674
function forceChatbotPosition() {
67-
// Handle all possible widget states
68-
const allWidgets = document.querySelectorAll('.dify-chatbot-widget, [class*="dify"], [id*="dify"]');
69-
const allWindows = document.querySelectorAll('#dify-chatbot-bubble-window, [class*="chat"], [class*="window"]');
75+
// Only target specific chatbot elements with very specific selectors
76+
const chatbotWidgets = document.querySelectorAll('.dify-chatbot-widget, #dify-chatbot-widget');
77+
const chatbotWindows = document.querySelectorAll('#dify-chatbot-bubble-window, .dify-chatbot-bubble-window');
78+
const chatbotButtons = document.querySelectorAll('#dify-chatbot-bubble-button, .dify-chatbot-bubble-button');
7079

71-
// Position all widget containers
72-
allWidgets.forEach(widget => {
80+
// Position chatbot widget containers only
81+
chatbotWidgets.forEach(widget => {
7382
widget.style.position = 'fixed';
7483
widget.style.bottom = '0';
7584
widget.style.right = '0';
@@ -80,8 +89,8 @@
8089
widget.style.transform = 'none';
8190
});
8291

83-
// Position all window elements
84-
allWindows.forEach(window => {
92+
// Position chatbot window elements only
93+
chatbotWindows.forEach(window => {
8594
window.style.position = 'fixed';
8695
window.style.bottom = '0';
8796
window.style.right = '0';
@@ -91,9 +100,9 @@
91100
window.style.transform = 'none';
92101
});
93102

94-
// Also handle any iframe that might be created
95-
const iframes = document.querySelectorAll('iframe[src*="dify"], iframe[src*="udify"]');
96-
iframes.forEach(iframe => {
103+
// Handle chatbot iframes specifically
104+
const chatbotIframes = document.querySelectorAll('iframe[src*="dify"], iframe[src*="udify"]');
105+
chatbotIframes.forEach(iframe => {
97106
iframe.style.position = 'fixed';
98107
iframe.style.bottom = '0';
99108
iframe.style.right = '0';
@@ -103,9 +112,9 @@
103112
iframe.style.transform = 'none';
104113
});
105114

106-
// Special handling for expanded state - target any element that might be the expanded window
107-
const expandedElements = document.querySelectorAll('[data-state="expanded"], [class*="expanded"], [style*="position: fixed"]');
108-
expandedElements.forEach(element => {
115+
// Only target expanded chatbot elements
116+
const expandedChatbotElements = document.querySelectorAll('.dify-chatbot-widget[data-state="expanded"], .dify-chatbot-widget .expanded');
117+
expandedChatbotElements.forEach(element => {
109118
element.style.position = 'fixed';
110119
element.style.bottom = '0';
111120
element.style.right = '0';
@@ -116,9 +125,9 @@
116125
element.style.zIndex = '1000';
117126
});
118127

119-
// Also force any element with a high z-index to stay at bottom
120-
const highZIndexElements = document.querySelectorAll('[style*="z-index: 999"], [style*="z-index: 1000"], [style*="z-index: 1001"]');
121-
highZIndexElements.forEach(element => {
128+
// Only force positioning on chatbot elements with high z-index
129+
const highZIndexChatbotElements = document.querySelectorAll('.dify-chatbot-widget[style*="z-index: 999"], .dify-chatbot-widget[style*="z-index: 1000"], .dify-chatbot-widget[style*="z-index: 1001"]');
130+
highZIndexChatbotElements.forEach(element => {
122131
if (element.style.position === 'fixed') {
123132
element.style.bottom = '0';
124133
element.style.right = '0';
@@ -127,9 +136,9 @@
127136
}
128137
});
129138

130-
// Make background elements more translucent to show rounded corners
131-
const allElements = document.querySelectorAll('.dify-chatbot-widget *');
132-
allElements.forEach(element => {
139+
// Make chatbot background elements more translucent to show rounded corners
140+
const chatbotElements = document.querySelectorAll('.dify-chatbot-widget *');
141+
chatbotElements.forEach(element => {
133142
const computedStyle = window.getComputedStyle(element);
134143
// Look for dark backgrounds that are likely the main content area
135144
if (computedStyle.backgroundColor &&
@@ -147,8 +156,7 @@
147156
});
148157

149158
// Ensure chat button is circular
150-
const chatButtons = document.querySelectorAll('[id*="bubble-button"], [class*="bubble-button"]');
151-
chatButtons.forEach(button => {
159+
chatbotButtons.forEach(button => {
152160
button.style.borderRadius = '50%';
153161
button.style.width = '60px';
154162
button.style.height = '60px';

0 commit comments

Comments
 (0)