diff --git a/change/@acedatacloud-nexior-16e884e3-a345-4751-8ca2-d39a462cf2aa.json b/change/@acedatacloud-nexior-16e884e3-a345-4751-8ca2-d39a462cf2aa.json
new file mode 100644
index 00000000..89b8fe15
--- /dev/null
+++ b/change/@acedatacloud-nexior-16e884e3-a345-4751-8ca2-d39a462cf2aa.json
@@ -0,0 +1,7 @@
+{
+ "type": "minor",
+ "comment": "update loading more",
+ "packageName": "@acedatacloud/nexior",
+ "email": "cqc@cuiqingcai.com",
+ "dependentChangeType": "patch"
+}
diff --git a/src/components/common/ScrollList.vue b/src/components/common/ScrollList.vue
new file mode 100644
index 00000000..5fc770c5
--- /dev/null
+++ b/src/components/common/ScrollList.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/common/TopLoading.vue b/src/components/common/TopLoading.vue
new file mode 100644
index 00000000..73e5e51b
--- /dev/null
+++ b/src/components/common/TopLoading.vue
@@ -0,0 +1,62 @@
+
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
diff --git a/src/components/nanobanana/RecentPanel.vue b/src/components/nanobanana/RecentPanel.vue
index 67af2f54..2dbadf73 100644
--- a/src/components/nanobanana/RecentPanel.vue
+++ b/src/components/nanobanana/RecentPanel.vue
@@ -2,9 +2,15 @@
-
+
-
+
@@ -15,13 +21,21 @@ import { defineComponent } from 'vue';
import TaskPreview from './task/Preview.vue';
import BotPlaceholder from '../common/BotPlaceholder.vue';
import NoTasks from '@/components/common/NoTasks.vue';
+import ScrollList from '@/components/common/ScrollList.vue';
export default defineComponent({
name: 'RecentPanel',
components: {
TaskPreview,
BotPlaceholder,
- NoTasks
+ NoTasks,
+ ScrollList
+ },
+ props: {
+ loading: {
+ type: Boolean,
+ default: false
+ }
},
emits: ['reach-top'],
data() {
@@ -38,11 +52,9 @@ export default defineComponent({
}
},
methods: {
- onHandleScroll() {
- const el = this.$refs.panel as HTMLElement;
- if (el.scrollTop === 0) {
- this.$emit('reach-top');
- }
+ getScrollElement(): HTMLElement | undefined {
+ const list = this.$refs.scrollList as any;
+ return list?.getScrollElement?.();
}
}
});
diff --git a/src/i18n/ar/common.json b/src/i18n/ar/common.json
index 2cde62f6..51cc776a 100644
--- a/src/i18n/ar/common.json
+++ b/src/i18n/ar/common.json
@@ -187,6 +187,10 @@
"message": "الحالة",
"description": "حالة الكيان"
},
+ "status.loading": {
+ "message": "جارٍ التحميل...",
+ "description": "نص الحالة المعروض أثناء تحميل المحتوى"
+ },
"entity.operation": {
"message": "العملية",
"description": "عملية الكيان"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "نص في شريط التنقل في الموقع لعرض صفحة Claude، يجب أن يبقى كما هو 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/de/common.json b/src/i18n/de/common.json
index 7c6ad776..840c10c9 100644
--- a/src/i18n/de/common.json
+++ b/src/i18n/de/common.json
@@ -187,6 +187,10 @@
"message": "Status",
"description": "Der Status der Entität"
},
+ "status.loading": {
+ "message": "Wird geladen...",
+ "description": "Statustext, der während des Ladens angezeigt wird"
+ },
"entity.operation": {
"message": "Operation",
"description": "Die Operation der Entität"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Text in der Navigationsleiste der Website, um die Claude-Seite anzuzeigen, muss als 'Claude' bleiben"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/el/common.json b/src/i18n/el/common.json
index f0c7aba8..6e0d5c61 100644
--- a/src/i18n/el/common.json
+++ b/src/i18n/el/common.json
@@ -187,6 +187,10 @@
"message": "Κατάσταση",
"description": "Η κατάσταση της οντότητας"
},
+ "status.loading": {
+ "message": "Φόρτωση...",
+ "description": "Κείμενο κατάστασης που εμφανίζεται κατά τη φόρτωση περιεχομένου"
+ },
"entity.operation": {
"message": "Λειτουργία",
"description": "Η λειτουργία της οντότητας"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Κείμενο στη γραμμή πλοήγησης του ιστότοπου για να εμφανιστεί η σελίδα Claude, πρέπει να παραμείνει ως 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/en/common.json b/src/i18n/en/common.json
index e890811f..67121257 100644
--- a/src/i18n/en/common.json
+++ b/src/i18n/en/common.json
@@ -187,6 +187,10 @@
"message": "Status",
"description": "The status of the entity"
},
+ "status.loading": {
+ "message": "Loading...",
+ "description": "Status text shown while content is loading"
+ },
"entity.operation": {
"message": "Operation",
"description": "The operation of the entity"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Text in the website navigation bar to display the Claude page, must remain as 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/es/common.json b/src/i18n/es/common.json
index 1ceee845..91cc8fc2 100644
--- a/src/i18n/es/common.json
+++ b/src/i18n/es/common.json
@@ -187,6 +187,10 @@
"message": "Estado",
"description": "El estado de la entidad"
},
+ "status.loading": {
+ "message": "Cargando...",
+ "description": "Texto de estado que se muestra mientras se carga el contenido"
+ },
"entity.operation": {
"message": "Operación",
"description": "La operación de la entidad"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Texto en la barra de navegación del sitio web para mostrar la página de Claude, debe permanecer como 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/fi/common.json b/src/i18n/fi/common.json
index 3a221fdf..59311540 100644
--- a/src/i18n/fi/common.json
+++ b/src/i18n/fi/common.json
@@ -187,6 +187,10 @@
"message": "Tila",
"description": "Entiteetin tila"
},
+ "status.loading": {
+ "message": "Ladataan...",
+ "description": "Tilateksti, joka näytetään sisällön latautuessa"
+ },
"entity.operation": {
"message": "Toiminto",
"description": "Entiteetin toiminto"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Teksti verkkosivuston navigointipalkissa, joka näyttää Claude-sivun, on säilytettävä 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/fr/common.json b/src/i18n/fr/common.json
index 5882aa38..661236e1 100644
--- a/src/i18n/fr/common.json
+++ b/src/i18n/fr/common.json
@@ -187,6 +187,10 @@
"message": "Statut",
"description": "Le statut de l'entité"
},
+ "status.loading": {
+ "message": "Chargement...",
+ "description": "Texte de statut affiché pendant le chargement du contenu"
+ },
"entity.operation": {
"message": "Opération",
"description": "L'opération de l'entité"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Texte dans la barre de navigation du site pour afficher la page Claude, doit rester 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/it/common.json b/src/i18n/it/common.json
index 7cdd48c8..6cd64028 100644
--- a/src/i18n/it/common.json
+++ b/src/i18n/it/common.json
@@ -187,6 +187,10 @@
"message": "Stato",
"description": "Lo stato dell'entità"
},
+ "status.loading": {
+ "message": "Caricamento...",
+ "description": "Testo di stato mostrato durante il caricamento dei contenuti"
+ },
"entity.operation": {
"message": "Operazione",
"description": "L'operazione dell'entità"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Testo nella barra di navigazione del sito web per visualizzare la pagina Claude, deve rimanere come 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/ja/common.json b/src/i18n/ja/common.json
index 5d13efa9..4d089e1e 100644
--- a/src/i18n/ja/common.json
+++ b/src/i18n/ja/common.json
@@ -187,6 +187,10 @@
"message": "ステータス",
"description": "エンティティのステータス"
},
+ "status.loading": {
+ "message": "読み込み中...",
+ "description": "コンテンツ読込中に表示されるステータス文言"
+ },
"entity.operation": {
"message": "操作",
"description": "エンティティの操作"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "ウェブサイトのナビゲーションバーに表示されるClaudeページのテキスト、'Claude'のままにする必要があります"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/ko/common.json b/src/i18n/ko/common.json
index 8feb1ddb..fd114c55 100644
--- a/src/i18n/ko/common.json
+++ b/src/i18n/ko/common.json
@@ -187,6 +187,10 @@
"message": "상태",
"description": "엔티티의 상태"
},
+ "status.loading": {
+ "message": "로딩 중...",
+ "description": "콘텐츠가 로딩될 때 표시되는 상태 문구"
+ },
"entity.operation": {
"message": "작업",
"description": "엔티티의 작업"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "웹사이트 내비게이션 바에서 Claude 페이지를 표시하는 텍스트, 'Claude'로 유지해야 함"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/pl/common.json b/src/i18n/pl/common.json
index f95373e7..d18e8a13 100644
--- a/src/i18n/pl/common.json
+++ b/src/i18n/pl/common.json
@@ -187,6 +187,10 @@
"message": "Status",
"description": "Status encji"
},
+ "status.loading": {
+ "message": "Ładowanie...",
+ "description": "Tekst statusu wyświetlany podczas wczytywania treści"
+ },
"entity.operation": {
"message": "Operacja",
"description": "Operacja encji"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Tekst w pasku nawigacyjnym strony internetowej, aby wyświetlić stronę Claude, musi pozostać jako 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/pt/common.json b/src/i18n/pt/common.json
index b5ba88ff..a83aeec2 100644
--- a/src/i18n/pt/common.json
+++ b/src/i18n/pt/common.json
@@ -187,6 +187,10 @@
"message": "Status",
"description": "Status da entidade"
},
+ "status.loading": {
+ "message": "Carregando...",
+ "description": "Texto de status exibido enquanto o conteúdo é carregado"
+ },
"entity.operation": {
"message": "Operação",
"description": "Operação da entidade"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Texto na barra de navegação do site para exibir a página Claude, deve permanecer como 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/ru/common.json b/src/i18n/ru/common.json
index 77c02d68..892eddf8 100644
--- a/src/i18n/ru/common.json
+++ b/src/i18n/ru/common.json
@@ -187,6 +187,10 @@
"message": "Статус",
"description": "Статус сущности"
},
+ "status.loading": {
+ "message": "Загрузка...",
+ "description": "Текст статуса, отображаемый во время загрузки контента"
+ },
"entity.operation": {
"message": "Операция",
"description": "Операция сущности"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Текст в навигационной панели сайта для отображения страницы Claude, должен оставаться как 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/sr/common.json b/src/i18n/sr/common.json
index 4440e713..aa6c536f 100644
--- a/src/i18n/sr/common.json
+++ b/src/i18n/sr/common.json
@@ -187,6 +187,10 @@
"message": "Status",
"description": "Status entiteta"
},
+ "status.loading": {
+ "message": "Учитавање...",
+ "description": "Текст статуса који се приказује док се садржај учитава"
+ },
"entity.operation": {
"message": "Operacija",
"description": "Operacija entiteta"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Tekst u navigacionoj traci sajta za prikaz Claude stranice, mora ostati kao 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/sv/common.json b/src/i18n/sv/common.json
index ee927487..dd0a2615 100644
--- a/src/i18n/sv/common.json
+++ b/src/i18n/sv/common.json
@@ -187,6 +187,10 @@
"message": "Status",
"description": "Status för enheten"
},
+ "status.loading": {
+ "message": "Laddar...",
+ "description": "Statustext som visas medan innehållet laddas"
+ },
"entity.operation": {
"message": "Operation",
"description": "Operationen för enheten"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Text i webbplatsens navigeringsfält för att visa Claude-sidan, måste förbli som 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/uk/common.json b/src/i18n/uk/common.json
index d5a262e0..a9963965 100644
--- a/src/i18n/uk/common.json
+++ b/src/i18n/uk/common.json
@@ -187,6 +187,10 @@
"message": "Статус",
"description": "Статус сутності"
},
+ "status.loading": {
+ "message": "Завантаження...",
+ "description": "Текст статусу, що показується під час завантаження контенту"
+ },
"entity.operation": {
"message": "Операція",
"description": "Операція сутності"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "Текст у навігаційній панелі сайту для відображення сторінки Claude, має залишатися 'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/i18n/zh-CN/common.json b/src/i18n/zh-CN/common.json
index 34ec7ad8..7d3a8c90 100644
--- a/src/i18n/zh-CN/common.json
+++ b/src/i18n/zh-CN/common.json
@@ -187,6 +187,10 @@
"message": "状态",
"description": "实体的状态"
},
+ "status.loading": {
+ "message": "加载中...",
+ "description": "内容加载时显示的状态文案"
+ },
"entity.operation": {
"message": "操作",
"description": "实体的操作"
diff --git a/src/i18n/zh-TW/common.json b/src/i18n/zh-TW/common.json
index 99ad25d0..89a96245 100644
--- a/src/i18n/zh-TW/common.json
+++ b/src/i18n/zh-TW/common.json
@@ -187,6 +187,10 @@
"message": "狀態",
"description": "實體的狀態"
},
+ "status.loading": {
+ "message": "載入中...",
+ "description": "內容載入時顯示的狀態文案"
+ },
"entity.operation": {
"message": "操作",
"description": "實體的操作"
@@ -575,4 +579,4 @@
"message": "Claude",
"description": "網站導航欄中的文本,用於顯示Claude頁面,必須保持為'Claude'"
}
-}
\ No newline at end of file
+}
diff --git a/src/pages/nanobanana/Index.vue b/src/pages/nanobanana/Index.vue
index ab4b7ac3..f4f11661 100644
--- a/src/pages/nanobanana/Index.vue
+++ b/src/pages/nanobanana/Index.vue
@@ -4,7 +4,7 @@
-
+
@@ -25,6 +25,7 @@ const CALLBACK_URL = 'https://webhook.acedata.cloud/nanobanana';
interface IData {
task: INanobananaTask | undefined;
job: number;
+ loading: boolean;
}
export default defineComponent({
@@ -38,13 +39,17 @@ export default defineComponent({
data(): IData {
return {
task: undefined,
- job: 0
+ job: 0,
+ loading: false
};
},
computed: {
- loading() {
+ applicationsLoading() {
return this.$store.state.nanobanana?.status?.getApplications === Status.Request;
},
+ tasksLoading() {
+ return this.$store.state.nanobanana?.status?.getTasks === Status.Request;
+ },
credential() {
return this.$store.state.nanobanana?.credential;
},
@@ -90,9 +95,35 @@ export default defineComponent({
methods: {
async onReachTop() {
console.debug('reached top');
- await this.onGetTasks({
- createdAtMax: this.tasks?.items?.[0]?.created_at
- });
+ if (this.loading || this.tasksLoading) {
+ return;
+ }
+ const total = this.tasks?.total;
+ const currentLength = this.tasks?.items?.length || 0;
+ if (total !== undefined && total <= currentLength) {
+ return;
+ }
+ const oldest = this.tasks?.items?.[0];
+ if (!oldest?.created_at) {
+ return;
+ }
+ const panel = this.$refs.recentPanel as any;
+ const el = panel?.getScrollElement?.() as HTMLElement | undefined;
+ const previousHeight = el?.scrollHeight || 0;
+ const previousScrollTop = el?.scrollTop || 0;
+ this.loading = true;
+ try {
+ await this.onGetTasks({
+ createdAtMax: oldest.created_at
+ });
+ await this.$nextTick();
+ if (el) {
+ const newHeight = el.scrollHeight;
+ el.scrollTop = newHeight - previousHeight + previousScrollTop;
+ }
+ } finally {
+ this.loading = false;
+ }
},
async onGetService() {
console.debug('start onGetService');
@@ -106,15 +137,14 @@ export default defineComponent({
await this.onGetTasks();
},
async onScrollDown() {
- setTimeout(() => {
- const el = document.querySelector('.tasks');
- if (el) {
- el.scrollTop = el.scrollHeight;
- }
- }, 1000);
+ await this.$nextTick();
+ const el = this.getTasksScrollElement();
+ if (el) {
+ el.scrollTop = el.scrollHeight;
+ }
},
async onGetTasks(payload?: { limit?: number; createdAtMin?: number; createdAtMax?: number }) {
- if (this.loading) {
+ if (this.applicationsLoading || this.tasksLoading) {
console.debug('loading');
return;
}
@@ -176,6 +206,10 @@ export default defineComponent({
await this.onScrollDown();
}, 1000);
});
+ },
+ getTasksScrollElement(): HTMLElement | undefined {
+ const panel = this.$refs.recentPanel as any;
+ return panel?.getScrollElement?.();
}
}
});
diff --git a/src/store/nanobanana/actions.ts b/src/store/nanobanana/actions.ts
index 44631fcc..711c08a5 100644
--- a/src/store/nanobanana/actions.ts
+++ b/src/store/nanobanana/actions.ts
@@ -129,18 +129,22 @@ export const getTasks = async (
createdAtMax
}: { offset?: number; limit?: number; createdAtMin?: number; createdAtMax?: number }
): Promise => {
+ state.status.getTasks = Status.Request;
return new Promise((resolve, reject) => {
console.debug('start to get tasks', offset, limit);
const credential = state.credential;
console.debug('current credential', credential);
const token = credential?.token;
if (!token) {
+ state.status.getTasks = Status.Error;
return reject('no token');
}
nanobananaOperator
.tasks(
{
userId: rootState?.user?.id,
+ offset,
+ limit,
createdAtMin,
createdAtMax,
type: 'images'
@@ -158,9 +162,11 @@ export const getTasks = async (
const mergedItems = mergeAndSortLists(existingItems, newItems);
commit('setTasksItems', mergedItems);
commit('setTasksTotal', response.data.count);
+ state.status.getTasks = Status.Success;
resolve(response.data.items);
})
.catch((error) => {
+ state.status.getTasks = Status.Error;
return reject(error);
});
});
diff --git a/src/store/nanobanana/mutations.ts b/src/store/nanobanana/mutations.ts
index 60c40f11..c02b12e3 100644
--- a/src/store/nanobanana/mutations.ts
+++ b/src/store/nanobanana/mutations.ts
@@ -2,6 +2,12 @@ import { IApplication, ICredential, INanobananaConfig, INanobananaTask, IService
import initialState from './state';
import { INanobananaState } from './models';
+const defaultTasks = {
+ items: undefined,
+ total: undefined,
+ active: undefined
+};
+
export const resetAll = (state: INanobananaState): void => {
Object.assign(state, initialState());
};
@@ -28,7 +34,7 @@ export const setConfig = (state: INanobananaState, payload: INanobananaConfig):
export const setTasksItems = (state: INanobananaState, payload: INanobananaTask[]): void => {
const newPayload = {
- ...state.tasks,
+ ...(state.tasks || defaultTasks),
items: payload
} as typeof state.tasks;
state.tasks = newPayload;
@@ -36,7 +42,7 @@ export const setTasksItems = (state: INanobananaState, payload: INanobananaTask[
export const setTasksTotal = (state: INanobananaState, payload: number): void => {
const newPayload = {
- ...state.tasks,
+ ...(state.tasks || defaultTasks),
total: payload
} as typeof state.tasks;
state.tasks = newPayload;
@@ -44,7 +50,7 @@ export const setTasksTotal = (state: INanobananaState, payload: number): void =>
export const setTasksActive = (state: INanobananaState, payload: INanobananaTask): void => {
const newPayload = {
- ...state.tasks,
+ ...(state.tasks || defaultTasks),
active: payload
} as typeof state.tasks;
state.tasks = newPayload;