aimeat 2.0.0 → 2.1.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/dist/locales/en.json +35 -1
- package/dist/locales/fi.json +35 -1
- package/dist/public/components/LinkPreview.js +101 -0
- package/dist/public/components/NotificationBell.js +18 -1
- package/dist/public/css/theme.css +57 -7
- package/dist/public/css/views/admin.css +8 -1
- package/dist/public/css/views/app-grant.css +18 -0
- package/dist/public/css/views/inbox.css +46 -0
- package/dist/public/css/views/portfolio.css +46 -0
- package/dist/public/css/views/profile.css +29 -4
- package/dist/public/js/services/apps.js +19 -3
- package/dist/public/js/services/messages-ai-prompts.js +38 -0
- package/dist/public/js/services/messages.js +26 -4
- package/dist/public/js/services/notebook.js +76 -0
- package/dist/public/js/services/unfurl.js +43 -0
- package/dist/public/lib/samples/LICENSE.md +11 -0
- package/dist/public/lib/samples/bass/A1.mp3 +0 -0
- package/dist/public/lib/samples/bass/B2.mp3 +0 -0
- package/dist/public/lib/samples/bass/D2.mp3 +0 -0
- package/dist/public/lib/samples/bass/E1.mp3 +0 -0
- package/dist/public/lib/samples/bass/E3.mp3 +0 -0
- package/dist/public/lib/samples/bass/G2.mp3 +0 -0
- package/dist/public/lib/samples/epiano/C2.mp3 +0 -0
- package/dist/public/lib/samples/epiano/C3.mp3 +0 -0
- package/dist/public/lib/samples/epiano/C4.mp3 +0 -0
- package/dist/public/lib/samples/epiano/C5.mp3 +0 -0
- package/dist/public/lib/samples/epiano/C6.mp3 +0 -0
- package/dist/public/lib/samples/epiano/G2.mp3 +0 -0
- package/dist/public/lib/samples/epiano/G3.mp3 +0 -0
- package/dist/public/lib/samples/epiano/G4.mp3 +0 -0
- package/dist/public/lib/samples/epiano/G5.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/A2.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/A4.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/B3.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/D3.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/E2.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/E4.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/E5.mp3 +0 -0
- package/dist/public/lib/samples/guitar-steel/G3.mp3 +0 -0
- package/dist/public/lib/samples/organ/C2.mp3 +0 -0
- package/dist/public/lib/samples/organ/C3.mp3 +0 -0
- package/dist/public/lib/samples/organ/C4.mp3 +0 -0
- package/dist/public/lib/samples/organ/C5.mp3 +0 -0
- package/dist/public/lib/samples/organ/C6.mp3 +0 -0
- package/dist/public/lib/samples/organ/G2.mp3 +0 -0
- package/dist/public/lib/samples/organ/G3.mp3 +0 -0
- package/dist/public/lib/samples/organ/G4.mp3 +0 -0
- package/dist/public/lib/samples/organ/G5.mp3 +0 -0
- package/dist/public/lib/samples/strings/C2.mp3 +0 -0
- package/dist/public/lib/samples/strings/C3.mp3 +0 -0
- package/dist/public/lib/samples/strings/C4.mp3 +0 -0
- package/dist/public/lib/samples/strings/C5.mp3 +0 -0
- package/dist/public/lib/samples/strings/C6.mp3 +0 -0
- package/dist/public/lib/samples/strings/G2.mp3 +0 -0
- package/dist/public/lib/samples/strings/G3.mp3 +0 -0
- package/dist/public/lib/samples/strings/G4.mp3 +0 -0
- package/dist/public/lib/samples/strings/G5.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/A3.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/A4.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/A5.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/C4.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/C5.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/E3.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/E4.mp3 +0 -0
- package/dist/public/lib/samples/trumpet/E5.mp3 +0 -0
- package/dist/public/spa.html +2 -0
- package/dist/public/views/app-grant.js +24 -4
- package/dist/public/views/portfolio.js +61 -6
- package/dist/public/views/profile/apps-tab.js +18 -1
- package/dist/public/views/profile/inbox-tab/ai-actions.js +86 -0
- package/dist/public/views/profile/inbox-tab/components.js +124 -9
- package/dist/public/views/profile/inbox-tab/helpers.js +26 -0
- package/dist/public/views/profile/inbox-tab/panels.js +18 -3
- package/dist/public/views/profile/inbox-tab/use-thread-ux.js +18 -1
- package/dist/public/views/profile/inbox-tab.js +46 -49
- package/dist/public/views/profile/landing-page.cards.js +7 -0
- package/dist/public/views/profile/landing-page.js +12 -1
- package/dist/public/views/profile/skills-tab.js +1 -1
- package/dist/public/views/public-workspace-viewer.js +1 -1
- package/dist/public/views/start.js +2 -1
- package/dist/scripts/build-sdk-libs.d.ts +16 -0
- package/dist/scripts/build-sdk-libs.d.ts.map +1 -0
- package/dist/scripts/build-sdk-libs.js +112 -0
- package/dist/scripts/build-sdk-libs.js.map +1 -0
- package/dist/src/cli/connect/auth.d.ts +15 -0
- package/dist/src/cli/connect/auth.d.ts.map +1 -1
- package/dist/src/cli/connect/auth.js +25 -6
- package/dist/src/cli/connect/auth.js.map +1 -1
- package/dist/src/cli/connect/keychain.d.ts +9 -0
- package/dist/src/cli/connect/keychain.d.ts.map +1 -1
- package/dist/src/cli/connect/keychain.js +21 -8
- package/dist/src/cli/connect/keychain.js.map +1 -1
- package/dist/src/cli/connect/mcp/tools/exchange.d.ts +18 -0
- package/dist/src/cli/connect/mcp/tools/exchange.d.ts.map +1 -0
- package/dist/src/cli/connect/mcp/tools/exchange.js +170 -0
- package/dist/src/cli/connect/mcp/tools/exchange.js.map +1 -0
- package/dist/src/cli/connect/mcp/tools/index.d.ts.map +1 -1
- package/dist/src/cli/connect/mcp/tools/index.js +2 -0
- package/dist/src/cli/connect/mcp/tools/index.js.map +1 -1
- package/dist/src/cli/connect/tool-call-defs-exchange.d.ts +3 -0
- package/dist/src/cli/connect/tool-call-defs-exchange.d.ts.map +1 -0
- package/dist/src/cli/connect/tool-call-defs-exchange.js +146 -0
- package/dist/src/cli/connect/tool-call-defs-exchange.js.map +1 -0
- package/dist/src/cli/connect/tool-call.d.ts.map +1 -1
- package/dist/src/cli/connect/tool-call.js +2 -0
- package/dist/src/cli/connect/tool-call.js.map +1 -1
- package/dist/src/commerce/session-service.d.ts +14 -0
- package/dist/src/commerce/session-service.d.ts.map +1 -1
- package/dist/src/commerce/session-service.js +1 -1
- package/dist/src/commerce/session-service.js.map +1 -1
- package/dist/src/data/app-templates/shells.d.ts +7 -3
- package/dist/src/data/app-templates/shells.d.ts.map +1 -1
- package/dist/src/data/app-templates/shells.js +10 -6
- package/dist/src/data/app-templates/shells.js.map +1 -1
- package/dist/src/data/appdev-pitfalls.d.ts +2 -0
- package/dist/src/data/appdev-pitfalls.d.ts.map +1 -1
- package/dist/src/data/appdev-pitfalls.js +24 -1
- package/dist/src/data/appdev-pitfalls.js.map +1 -1
- package/dist/src/generated/api-types.d.ts +1565 -9
- package/dist/src/generated/api-types.d.ts.map +1 -1
- package/dist/src/mcp/annotations.d.ts.map +1 -1
- package/dist/src/mcp/annotations.js +20 -0
- package/dist/src/mcp/annotations.js.map +1 -1
- package/dist/src/mcp/apps.d.ts.map +1 -1
- package/dist/src/mcp/apps.js +8 -4
- package/dist/src/mcp/apps.js.map +1 -1
- package/dist/src/mcp/catalog/definitions/exchange.d.ts +18 -0
- package/dist/src/mcp/catalog/definitions/exchange.d.ts.map +1 -0
- package/dist/src/mcp/catalog/definitions/exchange.js +182 -0
- package/dist/src/mcp/catalog/definitions/exchange.js.map +1 -0
- package/dist/src/mcp/catalog/definitions.d.ts.map +1 -1
- package/dist/src/mcp/catalog/definitions.js +2 -0
- package/dist/src/mcp/catalog/definitions.js.map +1 -1
- package/dist/src/mcp/catalog/scopes.d.ts.map +1 -1
- package/dist/src/mcp/catalog/scopes.js +22 -0
- package/dist/src/mcp/catalog/scopes.js.map +1 -1
- package/dist/src/mcp/catalog/surfaces.d.ts.map +1 -1
- package/dist/src/mcp/catalog/surfaces.js +14 -0
- package/dist/src/mcp/catalog/surfaces.js.map +1 -1
- package/dist/src/mcp/exchange-run.d.ts +5 -0
- package/dist/src/mcp/exchange-run.d.ts.map +1 -0
- package/dist/src/mcp/exchange-run.js +226 -0
- package/dist/src/mcp/exchange-run.js.map +1 -0
- package/dist/src/mcp/exchange.d.ts +5 -0
- package/dist/src/mcp/exchange.d.ts.map +1 -0
- package/dist/src/mcp/exchange.js +351 -0
- package/dist/src/mcp/exchange.js.map +1 -0
- package/dist/src/mcp/extensions.d.ts.map +1 -1
- package/dist/src/mcp/extensions.js +11 -0
- package/dist/src/mcp/extensions.js.map +1 -1
- package/dist/src/mcp/index.d.ts.map +1 -1
- package/dist/src/mcp/index.js +6 -2
- package/dist/src/mcp/index.js.map +1 -1
- package/dist/src/models/app-tool-schemas.d.ts +55 -1
- package/dist/src/models/app-tool-schemas.d.ts.map +1 -1
- package/dist/src/models/app-tool-schemas.js +20 -1
- package/dist/src/models/app-tool-schemas.js.map +1 -1
- package/dist/src/models/offer-schemas.d.ts +2 -2
- package/dist/src/models/schemas.d.ts +1 -0
- package/dist/src/models/schemas.d.ts.map +1 -1
- package/dist/src/models/schemas.js +3 -0
- package/dist/src/models/schemas.js.map +1 -1
- package/dist/src/routes/agents/device-auth.d.ts +4 -0
- package/dist/src/routes/agents/device-auth.d.ts.map +1 -1
- package/dist/src/routes/agents/device-auth.js +19 -4
- package/dist/src/routes/agents/device-auth.js.map +1 -1
- package/dist/src/routes/app-grants.d.ts +6 -0
- package/dist/src/routes/app-grants.d.ts.map +1 -1
- package/dist/src/routes/app-grants.js +35 -2
- package/dist/src/routes/app-grants.js.map +1 -1
- package/dist/src/routes/apps/fork-manage.d.ts.map +1 -1
- package/dist/src/routes/apps/fork-manage.js +24 -1
- package/dist/src/routes/apps/fork-manage.js.map +1 -1
- package/dist/src/routes/apps/publish.d.ts +2 -0
- package/dist/src/routes/apps/publish.d.ts.map +1 -1
- package/dist/src/routes/apps/publish.js +27 -1
- package/dist/src/routes/apps/publish.js.map +1 -1
- package/dist/src/routes/apps-cost.d.ts +25 -0
- package/dist/src/routes/apps-cost.d.ts.map +1 -0
- package/dist/src/routes/apps-cost.js +107 -0
- package/dist/src/routes/apps-cost.js.map +1 -0
- package/dist/src/routes/exchange-market.d.ts +28 -0
- package/dist/src/routes/exchange-market.d.ts.map +1 -0
- package/dist/src/routes/exchange-market.js +454 -0
- package/dist/src/routes/exchange-market.js.map +1 -0
- package/dist/src/routes/exchange.d.ts +33 -0
- package/dist/src/routes/exchange.d.ts.map +1 -0
- package/dist/src/routes/exchange.js +395 -0
- package/dist/src/routes/exchange.js.map +1 -0
- package/dist/src/routes/extensions/entitlement-gate.d.ts +33 -0
- package/dist/src/routes/extensions/entitlement-gate.d.ts.map +1 -0
- package/dist/src/routes/extensions/entitlement-gate.js +143 -0
- package/dist/src/routes/extensions/entitlement-gate.js.map +1 -0
- package/dist/src/routes/extensions/manifest.d.ts +9 -0
- package/dist/src/routes/extensions/manifest.d.ts.map +1 -1
- package/dist/src/routes/extensions/manifest.js +33 -1
- package/dist/src/routes/extensions/manifest.js.map +1 -1
- package/dist/src/routes/extensions/paywall.d.ts.map +1 -1
- package/dist/src/routes/extensions/paywall.js +9 -0
- package/dist/src/routes/extensions/paywall.js.map +1 -1
- package/dist/src/routes/federation-sync/messaging.d.ts.map +1 -1
- package/dist/src/routes/federation-sync/messaging.js +3 -1
- package/dist/src/routes/federation-sync/messaging.js.map +1 -1
- package/dist/src/routes/ghii/recovery.d.ts +2 -0
- package/dist/src/routes/ghii/recovery.d.ts.map +1 -1
- package/dist/src/routes/ghii/recovery.js +7 -0
- package/dist/src/routes/ghii/recovery.js.map +1 -1
- package/dist/src/routes/ghii/register-login.d.ts +4 -0
- package/dist/src/routes/ghii/register-login.d.ts.map +1 -1
- package/dist/src/routes/ghii/register-login.js +45 -22
- package/dist/src/routes/ghii/register-login.js.map +1 -1
- package/dist/src/routes/ghii/web-verify.d.ts +5 -0
- package/dist/src/routes/ghii/web-verify.d.ts.map +1 -1
- package/dist/src/routes/ghii/web-verify.js +24 -3
- package/dist/src/routes/ghii/web-verify.js.map +1 -1
- package/dist/src/routes/libs/sdk-serve.d.ts +11 -0
- package/dist/src/routes/libs/sdk-serve.d.ts.map +1 -0
- package/dist/src/routes/libs/sdk-serve.js +53 -0
- package/dist/src/routes/libs/sdk-serve.js.map +1 -0
- package/dist/src/routes/libs.d.ts +7 -1
- package/dist/src/routes/libs.d.ts.map +1 -1
- package/dist/src/routes/libs.js +65 -146
- package/dist/src/routes/libs.js.map +1 -1
- package/dist/src/routes/messages.d.ts +3 -0
- package/dist/src/routes/messages.d.ts.map +1 -1
- package/dist/src/routes/messages.js +9 -0
- package/dist/src/routes/messages.js.map +1 -1
- package/dist/src/routes/notifications.d.ts +6 -3
- package/dist/src/routes/notifications.d.ts.map +1 -1
- package/dist/src/routes/notifications.js +32 -3
- package/dist/src/routes/notifications.js.map +1 -1
- package/dist/src/routes/organisms/workspace-access.d.ts.map +1 -1
- package/dist/src/routes/organisms/workspace-access.js +38 -20
- package/dist/src/routes/organisms/workspace-access.js.map +1 -1
- package/dist/src/routes/unfurl.d.ts +27 -0
- package/dist/src/routes/unfurl.d.ts.map +1 -0
- package/dist/src/routes/unfurl.js +180 -0
- package/dist/src/routes/unfurl.js.map +1 -0
- package/dist/src/routes/upload.d.ts +2 -0
- package/dist/src/routes/upload.d.ts.map +1 -1
- package/dist/src/routes/upload.js +7 -0
- package/dist/src/routes/upload.js.map +1 -1
- package/dist/src/routes/webmcp.d.ts +3 -0
- package/dist/src/routes/webmcp.d.ts.map +1 -1
- package/dist/src/routes/webmcp.js +55 -0
- package/dist/src/routes/webmcp.js.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.d.ts +1 -0
- package/dist/src/server-bootstrap/routes-loader.d.ts.map +1 -1
- package/dist/src/server-bootstrap/routes-loader.js +8 -0
- package/dist/src/server-bootstrap/routes-loader.js.map +1 -1
- package/dist/src/services/agent-face.d.ts +10 -2
- package/dist/src/services/agent-face.d.ts.map +1 -1
- package/dist/src/services/agent-face.js +10 -4
- package/dist/src/services/agent-face.js.map +1 -1
- package/dist/src/services/app-tool-interfaces.d.ts +37 -0
- package/dist/src/services/app-tool-interfaces.d.ts.map +1 -0
- package/dist/src/services/app-tool-interfaces.js +101 -0
- package/dist/src/services/app-tool-interfaces.js.map +1 -0
- package/dist/src/services/build-app-prompt.d.ts +3 -0
- package/dist/src/services/build-app-prompt.d.ts.map +1 -1
- package/dist/src/services/build-app-prompt.js +12 -1
- package/dist/src/services/build-app-prompt.js.map +1 -1
- package/dist/src/services/contacts.d.ts +25 -1
- package/dist/src/services/contacts.d.ts.map +1 -1
- package/dist/src/services/contacts.js +30 -0
- package/dist/src/services/contacts.js.map +1 -1
- package/dist/src/services/entitlement-money.d.ts +55 -0
- package/dist/src/services/entitlement-money.d.ts.map +1 -0
- package/dist/src/services/entitlement-money.js +68 -0
- package/dist/src/services/entitlement-money.js.map +1 -0
- package/dist/src/services/exchange-market.d.ts +247 -0
- package/dist/src/services/exchange-market.d.ts.map +1 -0
- package/dist/src/services/exchange-market.js +254 -0
- package/dist/src/services/exchange-market.js.map +1 -0
- package/dist/src/services/exchange-proposals.d.ts +47 -0
- package/dist/src/services/exchange-proposals.d.ts.map +1 -0
- package/dist/src/services/exchange-proposals.js +71 -0
- package/dist/src/services/exchange-proposals.js.map +1 -0
- package/dist/src/services/exchange-work.d.ts +30 -0
- package/dist/src/services/exchange-work.d.ts.map +1 -0
- package/dist/src/services/exchange-work.js +43 -0
- package/dist/src/services/exchange-work.js.map +1 -0
- package/dist/src/services/message-send.d.ts.map +1 -1
- package/dist/src/services/message-send.js +4 -1
- package/dist/src/services/message-send.js.map +1 -1
- package/dist/src/services/metered-entitlements.d.ts +203 -0
- package/dist/src/services/metered-entitlements.d.ts.map +1 -0
- package/dist/src/services/metered-entitlements.js +264 -0
- package/dist/src/services/metered-entitlements.js.map +1 -0
- package/dist/src/services/notify.d.ts +7 -0
- package/dist/src/services/notify.d.ts.map +1 -1
- package/dist/src/services/notify.js +35 -0
- package/dist/src/services/notify.js.map +1 -1
- package/dist/src/services/owner-memory.d.ts +16 -0
- package/dist/src/services/owner-memory.d.ts.map +1 -1
- package/dist/src/services/owner-memory.js +23 -0
- package/dist/src/services/owner-memory.js.map +1 -1
- package/dist/src/services/owner-provisioning.d.ts +5 -0
- package/dist/src/services/owner-provisioning.d.ts.map +1 -1
- package/dist/src/services/owner-provisioning.js +20 -2
- package/dist/src/services/owner-provisioning.js.map +1 -1
- package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts +1 -0
- package/dist/src/storage/providers/postgres-kysely/methods/apps.d.ts.map +1 -1
- package/dist/src/storage/providers/postgres-kysely/methods/apps.js +2 -0
- package/dist/src/storage/providers/postgres-kysely/methods/apps.js.map +1 -1
- package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts +1 -0
- package/dist/src/storage/providers/postgres-kysely/methods/identity.d.ts.map +1 -1
- package/dist/src/storage/providers/postgres-kysely/methods/identity.js +4 -0
- package/dist/src/storage/providers/postgres-kysely/methods/identity.js.map +1 -1
- package/dist/src/storage/providers/postgres-kysely/migrations/0011_unique_verified_email.sql +25 -0
- package/dist/src/storage/providers/sqlite/methods/apps.d.ts +1 -0
- package/dist/src/storage/providers/sqlite/methods/apps.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/methods/apps.js +2 -0
- package/dist/src/storage/providers/sqlite/methods/apps.js.map +1 -1
- package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts +1 -0
- package/dist/src/storage/providers/sqlite/methods/identity-nodes.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/methods/identity-nodes.js +4 -0
- package/dist/src/storage/providers/sqlite/methods/identity-nodes.js.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.d.ts.map +1 -1
- package/dist/src/storage/providers/sqlite/schema.js +20 -0
- package/dist/src/storage/providers/sqlite/schema.js.map +1 -1
- package/dist/src/storage/repositories/app.repository.d.ts +0 -0
- package/dist/src/storage/repositories/app.repository.d.ts.map +1 -1
- package/dist/src/storage/repositories/identity.repository.d.ts +6 -0
- package/dist/src/storage/repositories/identity.repository.d.ts.map +1 -1
- package/dist/src/storage/types/apps.d.ts +1 -0
- package/dist/src/storage/types/apps.d.ts.map +1 -1
- package/dist/src/storage/types/organisms-federation.d.ts +21 -0
- package/dist/src/storage/types/organisms-federation.d.ts.map +1 -1
- package/dist/src/utils/app-mobile-lint.d.ts +17 -0
- package/dist/src/utils/app-mobile-lint.d.ts.map +1 -0
- package/dist/src/utils/app-mobile-lint.js +40 -0
- package/dist/src/utils/app-mobile-lint.js.map +1 -0
- package/dist/static/app-catalog/_template.html +12 -77
- package/dist/static/app-catalog/js/apps-io.js +51 -165
- package/dist/static/app-catalog/js/cost.js +100 -0
- package/dist/static/app-catalog/js/db.js +23 -93
- package/dist/static/app-catalog/js/detail.js +158 -24
- package/dist/static/app-catalog/js/favorites.js +71 -0
- package/dist/static/app-catalog/js/i18n-data.js +90 -16
- package/dist/static/app-catalog/js/main.js +23 -103
- package/dist/static/app-catalog/js/migrate.js +88 -0
- package/dist/static/app-catalog/js/monetize.js +1 -1
- package/dist/static/app-catalog/js/promote.js +70 -0
- package/dist/static/app-catalog/js/render.js +26 -139
- package/dist/static/app-catalog/js/server-io.js +126 -223
- package/dist/static/app-catalog/js/settings.js +11 -204
- package/dist/static/app-catalog/styles/app-catalog.css +40 -0
- package/dist/static/app-catalog.html +790 -912
- package/dist/static/sdk-libs/_core/config.js +52 -0
- package/dist/static/sdk-libs/_core/http.js +52 -0
- package/dist/static/sdk-libs/_core/namespace.js +33 -0
- package/dist/static/sdk-libs/_core/sdk-globals.d.ts +50 -0
- package/dist/static/sdk-libs/_core/session.js +66 -0
- package/dist/static/sdk-libs/agentface/index.js +102 -0
- package/dist/static/sdk-libs/agents/index.js +267 -0
- package/dist/static/sdk-libs/ai/index.js +153 -0
- package/dist/static/sdk-libs/audio/core.js +111 -0
- package/dist/static/sdk-libs/audio/index.js +380 -0
- package/dist/static/sdk-libs/audio/instruments.js +369 -0
- package/dist/static/sdk-libs/auth/config.js +46 -0
- package/dist/static/sdk-libs/auth/crypto.js +166 -0
- package/dist/static/sdk-libs/auth/events.js +27 -0
- package/dist/static/sdk-libs/auth/i18n.js +64 -0
- package/dist/static/sdk-libs/auth/index.js +37 -0
- package/dist/static/sdk-libs/auth/modal.js +545 -0
- package/dist/static/sdk-libs/auth/pill.js +167 -0
- package/dist/static/sdk-libs/auth/session.js +792 -0
- package/dist/static/sdk-libs/auth/signup.js +232 -0
- package/dist/static/sdk-libs/auth/theme.js +96 -0
- package/dist/static/sdk-libs/capabilities/index.js +179 -0
- package/dist/static/sdk-libs/commerce/index.js +243 -0
- package/dist/static/sdk-libs/data/index.js +188 -0
- package/dist/static/sdk-libs/dist/aimeat-agentface.js +91 -0
- package/dist/static/sdk-libs/dist/aimeat-agents.js +315 -0
- package/dist/static/sdk-libs/dist/aimeat-ai.js +168 -0
- package/dist/static/sdk-libs/dist/aimeat-audio.js +979 -0
- package/dist/static/sdk-libs/dist/aimeat-auth.js +1831 -0
- package/dist/static/sdk-libs/dist/aimeat-capabilities.js +177 -0
- package/dist/static/sdk-libs/dist/aimeat-commerce.js +265 -0
- package/dist/static/sdk-libs/dist/aimeat-data.js +205 -0
- package/dist/static/sdk-libs/dist/aimeat-editor.js +299 -0
- package/dist/static/sdk-libs/dist/aimeat-header.js +270 -0
- package/dist/static/sdk-libs/dist/aimeat-intake.js +94 -0
- package/dist/static/sdk-libs/dist/aimeat-live.js +265 -0
- package/dist/static/sdk-libs/dist/aimeat-markdown.js +602 -0
- package/dist/static/sdk-libs/dist/aimeat-organism.js +394 -0
- package/dist/static/sdk-libs/dist/aimeat-portfolio-standalone.js +90 -0
- package/dist/static/sdk-libs/dist/aimeat-social.js +157 -0
- package/dist/static/sdk-libs/dist/aimeat-speech.js +300 -0
- package/dist/static/sdk-libs/dist/aimeat-storage.js +210 -0
- package/dist/static/sdk-libs/dist/aimeat-tunnel.js +383 -0
- package/dist/static/sdk-libs/dist/aimeat-wallet.js +118 -0
- package/dist/static/sdk-libs/dist/aimeat-webmcp.js +187 -0
- package/dist/static/sdk-libs/dist/aimeat-work.js +213 -0
- package/dist/static/sdk-libs/dist/aimeat-workflows.js +147 -0
- package/dist/static/sdk-libs/editor/index.js +229 -0
- package/dist/static/sdk-libs/header/index.js +249 -0
- package/dist/static/sdk-libs/intake/index.js +75 -0
- package/dist/static/sdk-libs/live/index.js +156 -0
- package/dist/static/sdk-libs/markdown/index.js +522 -0
- package/dist/static/sdk-libs/organism/index.js +381 -0
- package/dist/static/sdk-libs/portfolio-standalone/index.js +78 -0
- package/dist/static/sdk-libs/social/index.js +140 -0
- package/dist/static/sdk-libs/speech/index.js +321 -0
- package/dist/static/sdk-libs/storage/index.js +189 -0
- package/dist/static/sdk-libs/tunnel/index.js +428 -0
- package/dist/static/sdk-libs/wallet/index.js +115 -0
- package/dist/static/sdk-libs/webmcp/index.js +185 -0
- package/dist/static/sdk-libs/work/index.js +191 -0
- package/dist/static/sdk-libs/workflows/index.js +113 -0
- package/package.json +5 -2
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
<!DOCTYPE html>
|
|
3
3
|
<!--
|
|
4
4
|
@file src/static/app-catalog.html
|
|
5
|
-
@description Self-contained "My Apps" launcher SPA (
|
|
6
|
-
publishing, and
|
|
7
|
-
|
|
5
|
+
@description Self-contained "My Apps" launcher SPA (SERVER-ONLY — no browser persistence) for
|
|
6
|
+
creating, publishing, and managing the owner's server apps. Creating an app publishes it to the
|
|
7
|
+
server (unlisted); nothing is stored in the browser. Runs published app HTML only inside a
|
|
8
|
+
sandboxed, opaque-origin iframe — never as a top-level document on the apex origin (H-2).
|
|
8
9
|
@structure Inline <style> theme; markup; large inline <script> exposing window._launcher.
|
|
9
10
|
@usage Served at GET /app-catalog.html (relaxed CSP) from server-bootstrap/static-files.ts.
|
|
10
11
|
@version-history
|
|
@@ -598,6 +599,46 @@
|
|
|
598
599
|
opacity: 1;
|
|
599
600
|
}
|
|
600
601
|
|
|
602
|
+
/* ── Server-backed favourite toggle (⭐ on any app / published card) ─── */
|
|
603
|
+
.fav-toggle {
|
|
604
|
+
position: absolute;
|
|
605
|
+
top: 6px;
|
|
606
|
+
left: 8px;
|
|
607
|
+
background: none;
|
|
608
|
+
border: none;
|
|
609
|
+
cursor: pointer;
|
|
610
|
+
font-size: 1rem;
|
|
611
|
+
line-height: 1;
|
|
612
|
+
padding: 2px;
|
|
613
|
+
opacity: .5;
|
|
614
|
+
transition: opacity var(--transition), transform var(--transition);
|
|
615
|
+
z-index: 2;
|
|
616
|
+
}
|
|
617
|
+
.fav-toggle:hover { opacity: 1; transform: scale(1.15); }
|
|
618
|
+
.fav-toggle.on { opacity: 1; }
|
|
619
|
+
.published-card { position: relative; }
|
|
620
|
+
.published-card .fav-toggle { left: auto; right: 8px; top: 8px; }
|
|
621
|
+
.fav-section-title {
|
|
622
|
+
font-size: 1rem;
|
|
623
|
+
font-weight: 700;
|
|
624
|
+
color: var(--text);
|
|
625
|
+
display: flex;
|
|
626
|
+
align-items: center;
|
|
627
|
+
gap: 8px;
|
|
628
|
+
margin: 0 0 .6rem;
|
|
629
|
+
}
|
|
630
|
+
.fav-section-count { opacity: .6; font-weight: 400; }
|
|
631
|
+
|
|
632
|
+
/* "Promoted" badge in the detail Promote section */
|
|
633
|
+
.dtl-badge-on {
|
|
634
|
+
font-size: .7rem;
|
|
635
|
+
font-weight: 600;
|
|
636
|
+
color: #34d399;
|
|
637
|
+
border: 1px solid #34d399;
|
|
638
|
+
border-radius: 10px;
|
|
639
|
+
padding: 1px 8px;
|
|
640
|
+
}
|
|
641
|
+
|
|
601
642
|
/* ── Card Menu Button ─────────────────────────────── */
|
|
602
643
|
|
|
603
644
|
.card-menu-btn {
|
|
@@ -2160,13 +2201,6 @@
|
|
|
2160
2201
|
<header>
|
|
2161
2202
|
<a class="aimeat-cta aimeat-home" id="aimeat-home-link" href="/" data-i18n-title="cta.backHome" title="Back to home"><span class="aimeat-cta-spark">⚡</span><span id="aimeat-home-label">aimeat.io</span></a>
|
|
2162
2203
|
<h1 data-i18n="header.title">My Apps</h1>
|
|
2163
|
-
<div class="mode-toggle-wrap">
|
|
2164
|
-
<span class="mode-caption" data-i18n="mode.caption" data-i18n-title="mode.caption.title" title="These toggle which browser-local apps you see — not server visibility">Local apps</span>
|
|
2165
|
-
<div class="mode-toggle">
|
|
2166
|
-
<button id="mode-global" class="mode-btn active" onclick="window._launcher.switchDbMode('global')" data-i18n="mode.global" data-i18n-title="mode.global.title" title="Shared across all accounts on this browser">🌐 Shared</button>
|
|
2167
|
-
<button id="mode-personal" class="mode-btn" onclick="window._launcher.switchDbMode('personal')" data-i18n="mode.personal" data-i18n-title="mode.personal.title" title="Private to your account">👤 Mine</button>
|
|
2168
|
-
</div>
|
|
2169
|
-
</div>
|
|
2170
2204
|
<input type="text" id="search-input" placeholder="Search apps..." data-i18n-ph="search.ph" autocomplete="off" spellcheck="false"/>
|
|
2171
2205
|
<div class="header-actions">
|
|
2172
2206
|
<span id="headerAuth" class="header-auth-pill"></span>
|
|
@@ -2267,10 +2301,10 @@
|
|
|
2267
2301
|
<p class="view-empty-hint" data-i18n="view.communityHint">Community apps are apps other people on this node have published. When someone publishes one, it shows up here.</p>
|
|
2268
2302
|
</div>
|
|
2269
2303
|
|
|
2270
|
-
<!--
|
|
2271
|
-
<div id="
|
|
2272
|
-
<
|
|
2273
|
-
<div id="
|
|
2304
|
+
<!-- ⭐ Favourites group (Library) — apps the owner favourited, pinned above "Your apps" -->
|
|
2305
|
+
<div id="favorites-section" data-view="library" style="display:none;margin:0 24px 1rem">
|
|
2306
|
+
<h2 class="fav-section-title"><span data-i18n="fav.title">⭐ Favourites</span> <span id="favorites-count" class="fav-section-count"></span></h2>
|
|
2307
|
+
<div id="favorites-grid" class="published-grid"></div>
|
|
2274
2308
|
</div>
|
|
2275
2309
|
|
|
2276
2310
|
<div id="local-apps-block" class="local-apps-block" data-view="library">
|
|
@@ -2291,18 +2325,10 @@
|
|
|
2291
2325
|
<div class="modal" id="add-app-modal">
|
|
2292
2326
|
<h2 id="modal-title" data-i18n="addModal.title">Add App</h2>
|
|
2293
2327
|
|
|
2294
|
-
<!-- Source tabs -->
|
|
2328
|
+
<!-- Source tabs — server-only: paste HTML or upload an HTML/ZIP file; it publishes to your account. -->
|
|
2295
2329
|
<div class="modal-tabs">
|
|
2296
|
-
<button class="modal-tab active" data-tab="
|
|
2330
|
+
<button class="modal-tab active" data-tab="paste" data-i18n="tab.paste">Paste</button>
|
|
2297
2331
|
<button class="modal-tab" data-tab="file" data-i18n="tab.file">File</button>
|
|
2298
|
-
<button class="modal-tab" data-tab="paste" data-i18n="tab.paste">Paste</button>
|
|
2299
|
-
<button class="modal-tab" data-tab="aimeat" data-i18n="tab.aimeat">AIMEAT</button>
|
|
2300
|
-
</div>
|
|
2301
|
-
|
|
2302
|
-
<!-- URL tab content -->
|
|
2303
|
-
<div class="tab-content active" id="tab-url">
|
|
2304
|
-
<label class="modal-label" for="app-url" data-i18n="addModal.url">App URL</label>
|
|
2305
|
-
<input type="url" id="app-url" class="modal-input" placeholder="https://example.com/app.html" autocomplete="off"/>
|
|
2306
2332
|
</div>
|
|
2307
2333
|
|
|
2308
2334
|
<!-- File tab content -->
|
|
@@ -2318,22 +2344,12 @@
|
|
|
2318
2344
|
</div>
|
|
2319
2345
|
</div>
|
|
2320
2346
|
|
|
2321
|
-
<!-- Paste tab content -->
|
|
2322
|
-
<div class="tab-content" id="tab-paste">
|
|
2347
|
+
<!-- Paste tab content (default) -->
|
|
2348
|
+
<div class="tab-content active" id="tab-paste">
|
|
2323
2349
|
<label class="modal-label" for="app-paste-code" data-i18n="addModal.paste">Paste HTML Source Code</label>
|
|
2324
2350
|
<textarea id="app-paste-code" class="modal-input" rows="10" placeholder="Paste your HTML source code here..." data-i18n-ph="addModal.pastePh" style="font-family:'Consolas','Monaco','Courier New',monospace;font-size:.8rem;resize:vertical;min-height:160px;line-height:1.4"></textarea>
|
|
2325
2351
|
</div>
|
|
2326
2352
|
|
|
2327
|
-
<!-- AIMEAT tab content -->
|
|
2328
|
-
<div class="tab-content" id="tab-aimeat">
|
|
2329
|
-
<p style="font-size:.85rem;color:var(--text-muted);margin-bottom:14px;line-height:1.5" data-i18n="addModal.aimeatHelp">
|
|
2330
|
-
Import apps from a connected AIMEAT server. Configure the server URL in Settings first.
|
|
2331
|
-
</p>
|
|
2332
|
-
<button type="button" class="modal-btn primary" onclick="window._launcher.importFromAimeat()" style="width:100%" data-i18n="addModal.fetch">
|
|
2333
|
-
Fetch Available Apps
|
|
2334
|
-
</button>
|
|
2335
|
-
</div>
|
|
2336
|
-
|
|
2337
2353
|
<!-- Common fields -->
|
|
2338
2354
|
<div class="modal-fields">
|
|
2339
2355
|
<div class="modal-row">
|
|
@@ -2468,21 +2484,6 @@
|
|
|
2468
2484
|
</div>
|
|
2469
2485
|
</div>
|
|
2470
2486
|
|
|
2471
|
-
<div class="settings-section">
|
|
2472
|
-
<div class="settings-section-title" data-i18n="settings.backup">Backup & Restore</div>
|
|
2473
|
-
<div class="settings-backup-actions">
|
|
2474
|
-
<button type="button" class="modal-btn secondary" onclick="window._launcher.exportBackup()" data-i18n="settings.exportJson">Export JSON</button>
|
|
2475
|
-
<button type="button" class="modal-btn secondary" onclick="document.getElementById('import-file-input').click()" data-i18n="settings.importJson">Import JSON</button>
|
|
2476
|
-
<button type="button" class="modal-btn secondary" onclick="window._launcher.removeDuplicateApps()" data-i18n="dedup.btn">🧹 Remove duplicate apps</button>
|
|
2477
|
-
<input type="file" id="import-file-input" accept=".json" hidden/>
|
|
2478
|
-
</div>
|
|
2479
|
-
</div>
|
|
2480
|
-
|
|
2481
|
-
<div class="settings-section" style="margin-bottom:0">
|
|
2482
|
-
<div class="settings-section-title" data-i18n="settings.danger">Danger Zone</div>
|
|
2483
|
-
<button type="button" class="modal-btn danger" onclick="window._launcher.clearAllData()" data-i18n="settings.clearAll">Clear All Data</button>
|
|
2484
|
-
</div>
|
|
2485
|
-
|
|
2486
2487
|
<div class="modal-actions" style="margin-top:24px">
|
|
2487
2488
|
<button type="button" class="modal-btn secondary" id="settings-cancel-btn" data-i18n="common.cancel">Cancel</button>
|
|
2488
2489
|
<button type="button" class="modal-btn primary" id="settings-save-btn" data-i18n="common.save">Save</button>
|
|
@@ -2509,18 +2510,6 @@
|
|
|
2509
2510
|
</div>
|
|
2510
2511
|
</div>
|
|
2511
2512
|
|
|
2512
|
-
<!-- AIMEAT Import Dialog (dynamically populated) -->
|
|
2513
|
-
<div id="aimeat-import-overlay" hidden>
|
|
2514
|
-
<div class="modal" id="aimeat-import-modal">
|
|
2515
|
-
<h2 data-i18n="import.title">Import from AIMEAT</h2>
|
|
2516
|
-
<div class="aimeat-app-list" id="aimeat-app-list"></div>
|
|
2517
|
-
<div class="modal-actions">
|
|
2518
|
-
<button type="button" class="modal-btn secondary" onclick="document.getElementById('aimeat-import-overlay').hidden = true" data-i18n="common.cancel">Cancel</button>
|
|
2519
|
-
<button type="button" class="modal-btn primary" onclick="window._launcher.processAimeatImport()" data-i18n="import.selected">Import Selected</button>
|
|
2520
|
-
</div>
|
|
2521
|
-
</div>
|
|
2522
|
-
</div>
|
|
2523
|
-
|
|
2524
2513
|
<!-- Publish Modal -->
|
|
2525
2514
|
<div id="publish-overlay" hidden>
|
|
2526
2515
|
<div class="modal" id="publish-modal">
|
|
@@ -2548,20 +2537,6 @@
|
|
|
2548
2537
|
</div>
|
|
2549
2538
|
</div>
|
|
2550
2539
|
|
|
2551
|
-
<!-- JSON Backup Import Modal (user-selected, duplicate-aware) -->
|
|
2552
|
-
<div id="json-import-overlay" hidden>
|
|
2553
|
-
<div class="modal" id="json-import-modal">
|
|
2554
|
-
<h2 data-i18n="jsonImport.title">📥 Import JSON backup</h2>
|
|
2555
|
-
<div id="json-import-status" style="margin:4px 0;font-size:.85rem;min-height:1.1em"></div>
|
|
2556
|
-
<div id="json-import-body" style="overflow-y:auto;max-height:55vh"></div>
|
|
2557
|
-
<div class="modal-actions">
|
|
2558
|
-
<button type="button" class="modal-btn secondary" onclick="document.getElementById('json-import-overlay').hidden = true" data-i18n="common.cancel">Cancel</button>
|
|
2559
|
-
<button type="button" class="modal-btn primary" id="json-import-btn" onclick="window._launcher.submitJsonImport()" data-i18n="srvImport.import">Import selected</button>
|
|
2560
|
-
</div>
|
|
2561
|
-
</div>
|
|
2562
|
-
</div>
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
2540
|
<!-- Backup Import Modal -->
|
|
2566
2541
|
<div id="backup-overlay" hidden>
|
|
2567
2542
|
<div class="modal" id="backup-modal">
|
|
@@ -2717,14 +2692,14 @@
|
|
|
2717
2692
|
"action.settings": "Settings",
|
|
2718
2693
|
"action.help": "Help",
|
|
2719
2694
|
"help.title": "❓ How this catalog works",
|
|
2720
|
-
"help.modesTitle": "
|
|
2721
|
-
"help.modes":
|
|
2695
|
+
"help.modesTitle": "Creating an app",
|
|
2696
|
+
"help.modes": "Add app lets you paste HTML or upload an HTML/ZIP file (or Generate with AI). It publishes straight to your account as UNLISTED — on the server but not yet public — so you can review it before listing. Nothing is stored only in your browser.",
|
|
2722
2697
|
"help.whereTitle": "Where your apps live",
|
|
2723
|
-
"help.where": "
|
|
2698
|
+
"help.where": "Every app lives on the server under your account — the catalog is server-only, so nothing is kept in this browser. Your apps follow you to any browser or device automatically.",
|
|
2724
2699
|
"help.sectionsTitle": "The two views",
|
|
2725
|
-
"help.sections": "Two tabs. Library = your apps, each as one card whose badge shows its publication state — Listed (
|
|
2700
|
+
"help.sections": "Two tabs. Library = your apps, each as one card whose badge shows its publication state — Listed (public in the catalogue) or Unlisted (on the server but hidden from the catalogue, still usable by you and anyone with the link). A purple Staging pill marks an app that also has an unpublished draft waiting. Community = apps other people have published.",
|
|
2726
2701
|
"help.backupTitle": '"Backup" means two different things',
|
|
2727
|
-
"help.backup": "The 💾 menu (top bar) exports/imports your SERVER apps + extensions as a .zip
|
|
2702
|
+
"help.backup": "The 💾 menu (top bar) exports/imports your SERVER apps + extensions as a .zip — a full server-side backup you can restore selectively.",
|
|
2728
2703
|
"help.standaloneTitle": "Which node this talks to",
|
|
2729
2704
|
"help.standalone": "This catalog is served by its node and always talks to that node (same-origin) — the Server URL in Settings is fixed to it. To use your own, open /app-catalog.html on your node: localhost, aimeat-desktop, and federated nodes each serve their OWN catalog.",
|
|
2730
2705
|
"action.theme": "Toggle light / dark",
|
|
@@ -2759,8 +2734,11 @@
|
|
|
2759
2734
|
"sec.parkedBlurb": "Only you can see and use these — they stay usable but are hidden from the public catalogue. Press Publish to move one back to Published Apps.",
|
|
2760
2735
|
"sec.recent": "🕒 Recently Opened",
|
|
2761
2736
|
"sec.local": "📚 Your apps",
|
|
2762
|
-
"sec.localNote": "One card per app. The badge shows its publication state — Listed (
|
|
2763
|
-
"sec.localHint": "💡
|
|
2737
|
+
"sec.localNote": "One card per app. The badge shows its publication state — Listed (public in the catalogue) or Unlisted (on the server but hidden from the public catalogue). A purple Staging pill marks an app that also has an unpublished draft.",
|
|
2738
|
+
"sec.localHint": "💡 Add app publishes to your account as unlisted — list it when it's ready to be public.",
|
|
2739
|
+
"fav.title": "⭐ Favourites",
|
|
2740
|
+
"fav.add": "Add to favourites",
|
|
2741
|
+
"fav.remove": "Remove from favourites",
|
|
2764
2742
|
"stats.apps": "apps",
|
|
2765
2743
|
"stats.stored": "stored",
|
|
2766
2744
|
"addModal.title": "Add App",
|
|
@@ -2826,6 +2804,8 @@
|
|
|
2826
2804
|
"publish.accessCodeHint": "4-64 chars. If set, only people with the code can download.",
|
|
2827
2805
|
"publish.submit": "Publish",
|
|
2828
2806
|
"publish.loginRequired": "Sign in to publish to AIMEAT. Anonymous publishing is disabled — use the Sign in button in the top bar.",
|
|
2807
|
+
"publish.savedUnlisted": "Saved — your app is on the server as unlisted. Open it and press List when you want it public.",
|
|
2808
|
+
"migrate.found": "You have {n} app(s) saved only in this browser from the old local catalog. The catalog is now server-only, so they no longer appear here. Download them as a JSON backup now? You can re-publish any you still want.",
|
|
2829
2809
|
"auth.signIn": "❤️ Sign In",
|
|
2830
2810
|
"auth.loggedIn": "logged in",
|
|
2831
2811
|
"auth.logout": "Logout",
|
|
@@ -2954,6 +2934,24 @@
|
|
|
2954
2934
|
"detail.iconLabel": "Icon (emoji)",
|
|
2955
2935
|
"detail.tagsLabel": "Tags (comma separated)",
|
|
2956
2936
|
"detail.descLabel": "Description",
|
|
2937
|
+
"detail.descEn": "Description (English)",
|
|
2938
|
+
"detail.descFi": "Description (Finnish)",
|
|
2939
|
+
"detail.translateEnFi": "Translate EN → FI",
|
|
2940
|
+
"detail.translateFiEn": "Translate FI → EN",
|
|
2941
|
+
"detail.translating": "Translating…",
|
|
2942
|
+
"detail.trDone": "Translated",
|
|
2943
|
+
"detail.trEmpty": "The AI returned nothing — try again.",
|
|
2944
|
+
"detail.trNeedSource": "Write the source-language description first.",
|
|
2945
|
+
"promote.title": "Promote",
|
|
2946
|
+
"promote.hint": "Showcase this app on your public profile with a short pitch. Fill English and/or Finnish; visitors see the one matching their language.",
|
|
2947
|
+
"promote.en": "Promotion text (English)",
|
|
2948
|
+
"promote.fi": "Promotion text (Finnish)",
|
|
2949
|
+
"promote.save": "Save promotion",
|
|
2950
|
+
"promote.remove": "Stop promoting",
|
|
2951
|
+
"promote.on": "Promoted",
|
|
2952
|
+
"promote.saving": "Saving…",
|
|
2953
|
+
"promote.saved": "Promoted on your profile.",
|
|
2954
|
+
"promote.removed": "No longer promoted.",
|
|
2957
2955
|
"detail.renameHint": "The app link stays the same — only the displayed name and description change.",
|
|
2958
2956
|
"detail.nameRequired": "Name cannot be empty.",
|
|
2959
2957
|
"detail.descRequired": "Description cannot be empty.",
|
|
@@ -3028,6 +3026,20 @@
|
|
|
3028
3026
|
"monetize.saved": "Tool manifest saved.",
|
|
3029
3027
|
"monetize.saveFailed": "Saving the tool manifest failed",
|
|
3030
3028
|
"monetize.needLogin": "Sign in to edit the tool manifest.",
|
|
3029
|
+
"cost.title": "📊 Cost & contracts — what this app sources",
|
|
3030
|
+
"cost.hint": "This app’s EXCHANGE contracts: durable metered entitlements it calls, with live spend against each budget and the platform rake. The per-call price comes from the provider; you set only the budget cap.",
|
|
3031
|
+
"cost.empty": "No EXCHANGE contracts yet — this app sources nothing priced.",
|
|
3032
|
+
"cost.summary": "{n} contract(s) · {spent} morsels spent · {calls} call(s)",
|
|
3033
|
+
"cost.capabilityCol": "Capability",
|
|
3034
|
+
"cost.providerCol": "Provider",
|
|
3035
|
+
"cost.priceCol": "Price / call",
|
|
3036
|
+
"cost.rakeCol": "Rake",
|
|
3037
|
+
"cost.budgetCol": "Budget (spent / cap)",
|
|
3038
|
+
"cost.stateCol": "State",
|
|
3039
|
+
"cost.uncapped": "uncapped",
|
|
3040
|
+
"cost.remaining": "{n} left",
|
|
3041
|
+
"cost.needLogin": "Sign in to view this app’s cost & contracts.",
|
|
3042
|
+
"cost.loadFailed": "Could not load cost & contracts",
|
|
3031
3043
|
"detail.editAccess": "Access code",
|
|
3032
3044
|
"detail.accessCodeHint": "Set or remove an optional code required to open this app.",
|
|
3033
3045
|
"detail.accessCodeLabel": "Access code",
|
|
@@ -3124,7 +3136,7 @@
|
|
|
3124
3136
|
"tag.favorites": "⭐ Favorites",
|
|
3125
3137
|
"empty.noApps": "No apps yet",
|
|
3126
3138
|
"empty.noAppsDesc": "Add your first app using the + button above",
|
|
3127
|
-
"empty.formats": "Supports: HTML files
|
|
3139
|
+
"empty.formats": "Supports: HTML files and ZIP packages",
|
|
3128
3140
|
"empty.noMatch": "No matches",
|
|
3129
3141
|
"empty.noMatchDesc": "No apps match the current filter. Try a different search term or tag."
|
|
3130
3142
|
},
|
|
@@ -3147,14 +3159,14 @@
|
|
|
3147
3159
|
"action.settings": "Asetukset",
|
|
3148
3160
|
"action.help": "Ohje",
|
|
3149
3161
|
"help.title": "❓ Miten tämä katalogi toimii",
|
|
3150
|
-
"help.modesTitle": "
|
|
3151
|
-
"help.modes":
|
|
3162
|
+
"help.modesTitle": "Sovelluksen luominen",
|
|
3163
|
+
"help.modes": "Lisää sovellus antaa liittää HTML:ää tai ladata HTML/ZIP-tiedoston (tai luoda sen tekoälyllä). Se julkaistaan suoraan tilillesi EI LISTALLA — palvelimelle mutta ei vielä julkiseksi — joten voit tarkistaa sen ennen listaamista. Mitään ei tallenneta vain selaimeesi.",
|
|
3152
3164
|
"help.whereTitle": "Missä appisi asuvat",
|
|
3153
|
-
"help.where": "
|
|
3165
|
+
"help.where": "Jokainen sovellus sijaitsee palvelimella tililläsi — katalogi on vain palvelinpohjainen, joten mitään ei säilytetä tässä selaimessa. Sovelluksesi seuraavat sinua mihin tahansa selaimeen tai laitteeseen automaattisesti.",
|
|
3154
3166
|
"help.sectionsTitle": "Kaksi näkymää",
|
|
3155
|
-
"help.sections": "Kaksi välilehteä. Kirjasto = sinun appisi, jokainen yhtenä korttina jonka merkki kertoo julkaisutilan — Listalla (
|
|
3167
|
+
"help.sections": "Kaksi välilehteä. Kirjasto = sinun appisi, jokainen yhtenä korttina jonka merkki kertoo julkaisutilan — Listalla (näkyy julkisessa katalogissa) tai Ei listalla (palvelimella mutta piilossa katalogista, sinä ja kuka tahansa linkillä voitte yhä käyttää). Violetti Staging-merkki kertoo että apilla on myös julkaisematon luonnos odottamassa. Yhteisö = muiden julkaisemat appit.",
|
|
3156
3168
|
"help.backupTitle": '"Varmuuskopio" tarkoittaa kahta eri asiaa',
|
|
3157
|
-
"help.backup": "💾-valikko (yläpalkki) vie/tuo PALVELIN-appisi + laajennukset .zip-tiedostona
|
|
3169
|
+
"help.backup": "💾-valikko (yläpalkki) vie/tuo PALVELIN-appisi + laajennukset .zip-tiedostona — täysi palvelinpuolen varmuuskopio, jonka voit palauttaa valikoiden.",
|
|
3158
3170
|
"help.standaloneTitle": "Mille nodelle tämä puhuu",
|
|
3159
3171
|
"help.standalone": "Tämän katalogin tarjoilee sen node, ja se puhuu aina sille nodelle (same-origin) — Asetusten Palvelin-URL on kiinnitetty siihen. Käyttääksesi omaa: avaa /app-catalog.html omalla nodellasi. localhost, aimeat-desktop ja federoidut nodet tarjoilevat kukin OMAN kataloginsa.",
|
|
3160
3172
|
"action.theme": "Vaihda vaalea / tumma",
|
|
@@ -3189,8 +3201,11 @@
|
|
|
3189
3201
|
"sec.parkedBlurb": "Vain sinä näet ja voit käyttää näitä — ne pysyvät käytettävissä mutta eivät näy julkisessa katalogissa. Paina Julkaise siirtääksesi takaisin julkaistuihin.",
|
|
3190
3202
|
"sec.recent": "🕒 Viimeksi avatut",
|
|
3191
3203
|
"sec.local": "📚 Sinun sovelluksesi",
|
|
3192
|
-
"sec.localNote": "Yksi kortti per sovellus. Merkki kertoo julkaisutilan — Listalla (
|
|
3193
|
-
"sec.localHint": "💡
|
|
3204
|
+
"sec.localNote": "Yksi kortti per sovellus. Merkki kertoo julkaisutilan — Listalla (näkyy julkisessa katalogissa) tai Ei listalla (palvelimella mutta piilossa julkisesta katalogista). Violetti Staging-merkki kertoo että apilla on myös julkaisematon luonnos.",
|
|
3205
|
+
"sec.localHint": "💡 Lisää sovellus julkaisee tilillesi ei-listalla — listaa se kun se on valmis julkiseksi.",
|
|
3206
|
+
"fav.title": "⭐ Suosikit",
|
|
3207
|
+
"fav.add": "Lisää suosikkeihin",
|
|
3208
|
+
"fav.remove": "Poista suosikeista",
|
|
3194
3209
|
"stats.apps": "sovellusta",
|
|
3195
3210
|
"stats.stored": "tallennettu",
|
|
3196
3211
|
"addModal.title": "Lisää sovellus",
|
|
@@ -3256,6 +3271,8 @@
|
|
|
3256
3271
|
"publish.accessCodeHint": "4–64 merkkiä. Jos asetettu, vain koodin tietävät voivat ladata.",
|
|
3257
3272
|
"publish.submit": "Julkaise",
|
|
3258
3273
|
"publish.loginRequired": "Kirjaudu sisään julkaistaksesi AIMEATiin. Anonyymi julkaisu on poistettu käytöstä — käytä yläpalkin Kirjaudu-painiketta.",
|
|
3274
|
+
"publish.savedUnlisted": "Tallennettu — sovelluksesi on palvelimella ei-listalla. Avaa se ja paina Listaa kun haluat sen julkiseksi.",
|
|
3275
|
+
"migrate.found": "Sinulla on {n} sovellus(ta) tallennettuna vain tähän selaimeen vanhasta paikallisesta katalogista. Katalogi on nyt vain palvelinpohjainen, joten ne eivät enää näy täällä. Ladataanko ne nyt JSON-varmuuskopiona? Voit julkaista uudelleen ne jotka haluat säilyttää.",
|
|
3259
3276
|
"auth.signIn": "❤️ Kirjaudu",
|
|
3260
3277
|
"auth.loggedIn": "kirjautunut",
|
|
3261
3278
|
"auth.logout": "Kirjaudu ulos",
|
|
@@ -3384,6 +3401,24 @@
|
|
|
3384
3401
|
"detail.iconLabel": "Kuvake (emoji)",
|
|
3385
3402
|
"detail.tagsLabel": "Tunnisteet (pilkulla eroteltuna)",
|
|
3386
3403
|
"detail.descLabel": "Kuvaus",
|
|
3404
|
+
"detail.descEn": "Kuvaus (englanti)",
|
|
3405
|
+
"detail.descFi": "Kuvaus (suomi)",
|
|
3406
|
+
"detail.translateEnFi": "Käännä EN → FI",
|
|
3407
|
+
"detail.translateFiEn": "Käännä FI → EN",
|
|
3408
|
+
"detail.translating": "Käännetään…",
|
|
3409
|
+
"detail.trDone": "Käännetty",
|
|
3410
|
+
"detail.trEmpty": "Tekoäly ei palauttanut mitään — yritä uudelleen.",
|
|
3411
|
+
"detail.trNeedSource": "Kirjoita ensin lähdekielinen kuvaus.",
|
|
3412
|
+
"promote.title": "Nosto",
|
|
3413
|
+
"promote.hint": "Nosta tämä sovellus julkiseen profiiliisi lyhyellä myyntipuheella. Täytä englanti ja/tai suomi; vierailijat näkevät kieltään vastaavan.",
|
|
3414
|
+
"promote.en": "Nostoteksti (englanti)",
|
|
3415
|
+
"promote.fi": "Nostoteksti (suomi)",
|
|
3416
|
+
"promote.save": "Tallenna nosto",
|
|
3417
|
+
"promote.remove": "Lopeta nostaminen",
|
|
3418
|
+
"promote.on": "Nostettu",
|
|
3419
|
+
"promote.saving": "Tallennetaan…",
|
|
3420
|
+
"promote.saved": "Nostettu profiiliisi.",
|
|
3421
|
+
"promote.removed": "Ei enää nostettu.",
|
|
3387
3422
|
"detail.renameHint": "Sovelluksen linkki pysyy samana — vain näytettävä nimi ja kuvaus muuttuvat.",
|
|
3388
3423
|
"detail.nameRequired": "Nimi ei voi olla tyhjä.",
|
|
3389
3424
|
"detail.descRequired": "Kuvaus ei voi olla tyhjä.",
|
|
@@ -3456,6 +3491,20 @@
|
|
|
3456
3491
|
"monetize.saved": "Työkalumanifesti tallennettu.",
|
|
3457
3492
|
"monetize.saveFailed": "Työkalumanifestin tallennus epäonnistui",
|
|
3458
3493
|
"monetize.needLogin": "Kirjaudu sisään muokataksesi työkalumanifestia.",
|
|
3494
|
+
"cost.title": "📊 Kulut & sopimukset — mitä tämä appi hankkii",
|
|
3495
|
+
"cost.hint": "Tämän appin EXCHANGE-sopimukset: pysyvät mitatut käyttöoikeudet joita se kutsuu, live-kulutus kutakin budjettia vasten ja alustan siivu. Kutsukohtainen hinta tulee tarjoajalta; sinä asetat vain budjettikaton.",
|
|
3496
|
+
"cost.empty": "Ei vielä EXCHANGE-sopimuksia — tämä appi ei hanki mitään hinnoiteltua.",
|
|
3497
|
+
"cost.summary": "{n} sopimus(ta) · {spent} morselia käytetty · {calls} kutsu(a)",
|
|
3498
|
+
"cost.capabilityCol": "Kyvykkyys",
|
|
3499
|
+
"cost.providerCol": "Tarjoaja",
|
|
3500
|
+
"cost.priceCol": "Hinta / kutsu",
|
|
3501
|
+
"cost.rakeCol": "Siivu",
|
|
3502
|
+
"cost.budgetCol": "Budjetti (käytetty / katto)",
|
|
3503
|
+
"cost.stateCol": "Tila",
|
|
3504
|
+
"cost.uncapped": "ei kattoa",
|
|
3505
|
+
"cost.remaining": "{n} jäljellä",
|
|
3506
|
+
"cost.needLogin": "Kirjaudu sisään nähdäksesi tämän appin kulut & sopimukset.",
|
|
3507
|
+
"cost.loadFailed": "Kulujen & sopimusten lataus epäonnistui",
|
|
3459
3508
|
"detail.skillDetach": "Irrota",
|
|
3460
3509
|
"detail.skillAttachError": "Taidon liittäminen epäonnistui",
|
|
3461
3510
|
"detail.editAccess": "Pääsykoodi",
|
|
@@ -3554,7 +3603,7 @@
|
|
|
3554
3603
|
"tag.favorites": "⭐ Suosikit",
|
|
3555
3604
|
"empty.noApps": "Ei vielä sovelluksia",
|
|
3556
3605
|
"empty.noAppsDesc": "Lisää ensimmäinen sovellus yllä olevalla +-painikkeella",
|
|
3557
|
-
"empty.formats": "Tukee: HTML-tiedostot
|
|
3606
|
+
"empty.formats": "Tukee: HTML-tiedostot ja ZIP-paketit",
|
|
3558
3607
|
"empty.noMatch": "Ei osumia",
|
|
3559
3608
|
"empty.noMatchDesc": "Mikään sovellus ei vastaa nykyistä suodatinta. Kokeile eri hakusanaa tai tunnistetta."
|
|
3560
3609
|
}
|
|
@@ -3677,128 +3726,25 @@
|
|
|
3677
3726
|
}
|
|
3678
3727
|
|
|
3679
3728
|
// src/static/app-catalog/js/db.js
|
|
3680
|
-
var
|
|
3681
|
-
var DB_VERSION = 2;
|
|
3682
|
-
var STORE_NAME2 = "apps";
|
|
3683
|
-
var dbInstance = null;
|
|
3684
|
-
var currentDbMode = localStorage.getItem("appCatalogMode") || "global";
|
|
3685
|
-
function getDbMode() {
|
|
3686
|
-
return currentDbMode;
|
|
3687
|
-
}
|
|
3688
|
-
function setDbMode(mode) {
|
|
3689
|
-
currentDbMode = mode;
|
|
3690
|
-
try {
|
|
3691
|
-
localStorage.setItem("appCatalogMode", mode);
|
|
3692
|
-
} catch (e) {
|
|
3693
|
-
}
|
|
3694
|
-
}
|
|
3695
|
-
function closeDbInstance() {
|
|
3696
|
-
if (dbInstance) {
|
|
3697
|
-
try {
|
|
3698
|
-
dbInstance.close();
|
|
3699
|
-
} catch (e) {
|
|
3700
|
-
}
|
|
3701
|
-
dbInstance = null;
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
function getDbName() {
|
|
3705
|
-
if (currentDbMode === "personal") {
|
|
3706
|
-
var owner = null;
|
|
3707
|
-
try {
|
|
3708
|
-
if (window.AIMEAT && window.AIMEAT.auth && window.AIMEAT.auth.getSession()) {
|
|
3709
|
-
owner = window.AIMEAT.auth.getSession().owner || null;
|
|
3710
|
-
}
|
|
3711
|
-
if (!owner) {
|
|
3712
|
-
var stored = localStorage.getItem("aimeat_session");
|
|
3713
|
-
if (stored) owner = JSON.parse(stored).owner || null;
|
|
3714
|
-
}
|
|
3715
|
-
} catch (e) {
|
|
3716
|
-
}
|
|
3717
|
-
if (owner) return DB_NAME_GLOBAL + "_" + owner;
|
|
3718
|
-
}
|
|
3719
|
-
return DB_NAME_GLOBAL;
|
|
3720
|
-
}
|
|
3721
|
-
function openDB() {
|
|
3722
|
-
var name = getDbName();
|
|
3723
|
-
if (dbInstance && dbInstance.name === name) return Promise.resolve(dbInstance);
|
|
3724
|
-
if (dbInstance) {
|
|
3725
|
-
dbInstance.close();
|
|
3726
|
-
dbInstance = null;
|
|
3727
|
-
}
|
|
3728
|
-
return new Promise(function(resolve, reject) {
|
|
3729
|
-
const request = indexedDB.open(name, DB_VERSION);
|
|
3730
|
-
request.onupgradeneeded = function(event) {
|
|
3731
|
-
const db = event.target.result;
|
|
3732
|
-
var store;
|
|
3733
|
-
if (!db.objectStoreNames.contains(STORE_NAME2)) {
|
|
3734
|
-
store = db.createObjectStore(STORE_NAME2, { keyPath: "id" });
|
|
3735
|
-
store.createIndex("tags", "tags", { multiEntry: true });
|
|
3736
|
-
store.createIndex("source", "source", { unique: false });
|
|
3737
|
-
store.createIndex("favorite", "favorite", { unique: false });
|
|
3738
|
-
store.createIndex("sortOrder", "sortOrder", { unique: false });
|
|
3739
|
-
} else {
|
|
3740
|
-
store = event.target.transaction.objectStore(STORE_NAME2);
|
|
3741
|
-
if (!store.indexNames.contains("sortOrder")) {
|
|
3742
|
-
store.createIndex("sortOrder", "sortOrder", { unique: false });
|
|
3743
|
-
}
|
|
3744
|
-
}
|
|
3745
|
-
};
|
|
3746
|
-
request.onsuccess = function(event) {
|
|
3747
|
-
dbInstance = event.target.result;
|
|
3748
|
-
resolve(dbInstance);
|
|
3749
|
-
};
|
|
3750
|
-
request.onerror = function(event) {
|
|
3751
|
-
reject(event.target.error);
|
|
3752
|
-
};
|
|
3753
|
-
});
|
|
3754
|
-
}
|
|
3729
|
+
var workingSet = [];
|
|
3755
3730
|
function getAllApps() {
|
|
3756
|
-
return
|
|
3757
|
-
return new Promise(function(resolve, reject) {
|
|
3758
|
-
const tx = db.transaction(STORE_NAME2, "readonly");
|
|
3759
|
-
const request = tx.objectStore(STORE_NAME2).getAll();
|
|
3760
|
-
request.onsuccess = function() {
|
|
3761
|
-
resolve(request.result);
|
|
3762
|
-
};
|
|
3763
|
-
request.onerror = function() {
|
|
3764
|
-
reject(request.error);
|
|
3765
|
-
};
|
|
3766
|
-
});
|
|
3767
|
-
});
|
|
3731
|
+
return Promise.resolve(workingSet.slice());
|
|
3768
3732
|
}
|
|
3769
3733
|
function saveApp(app) {
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
tx.objectStore(STORE_NAME2).put(app);
|
|
3774
|
-
tx.oncomplete = function() {
|
|
3775
|
-
resolve();
|
|
3776
|
-
};
|
|
3777
|
-
tx.onerror = function() {
|
|
3778
|
-
reject(tx.error);
|
|
3779
|
-
};
|
|
3780
|
-
tx.onabort = function() {
|
|
3781
|
-
reject(tx.error);
|
|
3782
|
-
};
|
|
3734
|
+
if (app && app.id) {
|
|
3735
|
+
var idx = workingSet.findIndex(function(a) {
|
|
3736
|
+
return a.id === app.id;
|
|
3783
3737
|
});
|
|
3784
|
-
|
|
3738
|
+
if (idx >= 0) workingSet[idx] = app;
|
|
3739
|
+
else workingSet.push(app);
|
|
3740
|
+
}
|
|
3741
|
+
return Promise.resolve();
|
|
3785
3742
|
}
|
|
3786
3743
|
function deleteApp(id) {
|
|
3787
|
-
|
|
3788
|
-
return
|
|
3789
|
-
const tx = db.transaction(STORE_NAME2, "readwrite");
|
|
3790
|
-
tx.objectStore(STORE_NAME2).delete(id);
|
|
3791
|
-
tx.oncomplete = function() {
|
|
3792
|
-
resolve();
|
|
3793
|
-
};
|
|
3794
|
-
tx.onerror = function() {
|
|
3795
|
-
reject(tx.error);
|
|
3796
|
-
};
|
|
3797
|
-
tx.onabort = function() {
|
|
3798
|
-
reject(tx.error);
|
|
3799
|
-
};
|
|
3800
|
-
});
|
|
3744
|
+
workingSet = workingSet.filter(function(a) {
|
|
3745
|
+
return a.id !== id;
|
|
3801
3746
|
});
|
|
3747
|
+
return Promise.resolve();
|
|
3802
3748
|
}
|
|
3803
3749
|
|
|
3804
3750
|
// src/static/app-catalog/js/ui.js
|
|
@@ -4372,9 +4318,9 @@
|
|
|
4372
4318
|
function loadPbCore() {
|
|
4373
4319
|
var config = loadConfig();
|
|
4374
4320
|
if (!config.aimeatUrl) return;
|
|
4375
|
-
var
|
|
4321
|
+
var base3 = config.aimeatUrl.replace(/\/+$/, "");
|
|
4376
4322
|
["new", "improve"].forEach(function(mode) {
|
|
4377
|
-
fetch(
|
|
4323
|
+
fetch(base3 + "/v1/prompts/build-app?mode=" + mode + "&lang=" + encodeURIComponent(getLang())).then(function(r) {
|
|
4378
4324
|
return r.json();
|
|
4379
4325
|
}).then(function(d) {
|
|
4380
4326
|
var body = d && d.data && d.data.body;
|
|
@@ -4391,8 +4337,8 @@
|
|
|
4391
4337
|
if (!sel) return;
|
|
4392
4338
|
var config = loadConfig();
|
|
4393
4339
|
if (!config.aimeatUrl) return;
|
|
4394
|
-
var
|
|
4395
|
-
fetch(
|
|
4340
|
+
var base3 = config.aimeatUrl.replace(/\/+$/, "");
|
|
4341
|
+
fetch(base3 + "/v1/app-templates?lang=" + encodeURIComponent(getLang())).then(function(r) {
|
|
4396
4342
|
return r.json();
|
|
4397
4343
|
}).then(function(d) {
|
|
4398
4344
|
var list = (d.data && d.data.templates || []).filter(function(t2) {
|
|
@@ -4416,7 +4362,7 @@
|
|
|
4416
4362
|
updatePbPreview();
|
|
4417
4363
|
return;
|
|
4418
4364
|
}
|
|
4419
|
-
fetch(
|
|
4365
|
+
fetch(base3 + "/v1/app-templates/" + encodeURIComponent(id)).then(function(r) {
|
|
4420
4366
|
return r.json();
|
|
4421
4367
|
}).then(function(d2) {
|
|
4422
4368
|
window.pbTemplate = d2.data && d2.data.template || null;
|
|
@@ -4442,8 +4388,8 @@
|
|
|
4442
4388
|
if (!wrap) return;
|
|
4443
4389
|
var config = loadConfig();
|
|
4444
4390
|
if (!config.aimeatUrl) return;
|
|
4445
|
-
var
|
|
4446
|
-
fetch(
|
|
4391
|
+
var base3 = config.aimeatUrl.replace(/\/+$/, "");
|
|
4392
|
+
fetch(base3 + "/v1/library-packs?lang=" + encodeURIComponent(getLang())).then(function(r) {
|
|
4447
4393
|
return r.json();
|
|
4448
4394
|
}).then(function(d) {
|
|
4449
4395
|
var all = d.data && d.data.packs || [];
|
|
@@ -4464,7 +4410,7 @@
|
|
|
4464
4410
|
cb.value = p.id;
|
|
4465
4411
|
cb.onchange = function() {
|
|
4466
4412
|
pbPackTouched[p.id] = true;
|
|
4467
|
-
if (cb.checked) loadPbPackDoc(
|
|
4413
|
+
if (cb.checked) loadPbPackDoc(base3, p.id);
|
|
4468
4414
|
else updatePbPreview();
|
|
4469
4415
|
};
|
|
4470
4416
|
var span = document.createElement("span");
|
|
@@ -4487,14 +4433,14 @@
|
|
|
4487
4433
|
if (desc && !desc._pbPackListener) {
|
|
4488
4434
|
desc._pbPackListener = true;
|
|
4489
4435
|
desc.addEventListener("input", function() {
|
|
4490
|
-
pbMatchPacksToIdea(
|
|
4436
|
+
pbMatchPacksToIdea(base3);
|
|
4491
4437
|
});
|
|
4492
4438
|
}
|
|
4493
|
-
pbMatchPacksToIdea(
|
|
4439
|
+
pbMatchPacksToIdea(base3);
|
|
4494
4440
|
}).catch(function() {
|
|
4495
4441
|
});
|
|
4496
4442
|
}
|
|
4497
|
-
function pbMatchPacksToIdea(
|
|
4443
|
+
function pbMatchPacksToIdea(base3) {
|
|
4498
4444
|
var desc = document.getElementById("pb-description");
|
|
4499
4445
|
var text = (desc && desc.value || "").toLowerCase();
|
|
4500
4446
|
pbPacks.forEach(function(p) {
|
|
@@ -4507,19 +4453,19 @@
|
|
|
4507
4453
|
});
|
|
4508
4454
|
if (hit && !cb.checked) {
|
|
4509
4455
|
cb.checked = true;
|
|
4510
|
-
loadPbPackDoc(
|
|
4456
|
+
loadPbPackDoc(base3, p.id);
|
|
4511
4457
|
} else if (!hit && cb.checked) {
|
|
4512
4458
|
cb.checked = false;
|
|
4513
4459
|
updatePbPreview();
|
|
4514
4460
|
}
|
|
4515
4461
|
});
|
|
4516
4462
|
}
|
|
4517
|
-
function loadPbPackDoc(
|
|
4463
|
+
function loadPbPackDoc(base3, id) {
|
|
4518
4464
|
if (pbPackDocs[id]) {
|
|
4519
4465
|
updatePbPreview();
|
|
4520
4466
|
return;
|
|
4521
4467
|
}
|
|
4522
|
-
fetch(
|
|
4468
|
+
fetch(base3 + "/v1/library-packs/" + encodeURIComponent(id)).then(function(r) {
|
|
4523
4469
|
return r.json();
|
|
4524
4470
|
}).then(function(d) {
|
|
4525
4471
|
var pack = d.data && d.data.pack;
|
|
@@ -4710,6 +4656,71 @@
|
|
|
4710
4656
|
preview.textContent = buildPromptFromBuilder();
|
|
4711
4657
|
}
|
|
4712
4658
|
|
|
4659
|
+
// src/static/app-catalog/js/promote.js
|
|
4660
|
+
var KEY = "app-catalog.promoted";
|
|
4661
|
+
var promoted = {};
|
|
4662
|
+
function base() {
|
|
4663
|
+
return (loadConfig().aimeatUrl || "").replace(/\/+$/, "");
|
|
4664
|
+
}
|
|
4665
|
+
function getPromotion(ref) {
|
|
4666
|
+
return promoted[ref] || null;
|
|
4667
|
+
}
|
|
4668
|
+
function getPromotedItems() {
|
|
4669
|
+
return Object.keys(promoted).map(function(ref) {
|
|
4670
|
+
return { ref, text: promoted[ref] || {} };
|
|
4671
|
+
});
|
|
4672
|
+
}
|
|
4673
|
+
function loadPromoted() {
|
|
4674
|
+
var token = getCortexOwnerToken();
|
|
4675
|
+
var b = base();
|
|
4676
|
+
if (!token || !b) {
|
|
4677
|
+
promoted = {};
|
|
4678
|
+
return Promise.resolve();
|
|
4679
|
+
}
|
|
4680
|
+
return fetch(b + "/v1/memory/" + encodeURIComponent(KEY), { headers: { "Authorization": "Bearer " + token } }).then(function(r) {
|
|
4681
|
+
return r.ok ? r.json() : null;
|
|
4682
|
+
}).then(function(j) {
|
|
4683
|
+
var items = j && j.data && j.data.value && Array.isArray(j.data.value.items) ? j.data.value.items : [];
|
|
4684
|
+
var map = {};
|
|
4685
|
+
items.forEach(function(it) {
|
|
4686
|
+
if (it && typeof it.ref === "string" && it.text && typeof it.text === "object") map[it.ref] = { en: it.text.en || "", fi: it.text.fi || "" };
|
|
4687
|
+
});
|
|
4688
|
+
promoted = map;
|
|
4689
|
+
}).catch(function() {
|
|
4690
|
+
});
|
|
4691
|
+
}
|
|
4692
|
+
function persist() {
|
|
4693
|
+
var token = getCortexOwnerToken();
|
|
4694
|
+
var b = base();
|
|
4695
|
+
if (!token || !b) return Promise.resolve();
|
|
4696
|
+
var items = getPromotedItems();
|
|
4697
|
+
return fetch(b + "/v1/memory", {
|
|
4698
|
+
method: "POST",
|
|
4699
|
+
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
|
|
4700
|
+
body: JSON.stringify({
|
|
4701
|
+
key: KEY,
|
|
4702
|
+
value: { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), items },
|
|
4703
|
+
visibility: "public"
|
|
4704
|
+
})
|
|
4705
|
+
}).catch(function() {
|
|
4706
|
+
});
|
|
4707
|
+
}
|
|
4708
|
+
function setPromotion(ref, text) {
|
|
4709
|
+
var en = text && text.en ? String(text.en).trim() : "";
|
|
4710
|
+
var fi = text && text.fi ? String(text.fi).trim() : "";
|
|
4711
|
+
var now;
|
|
4712
|
+
if (!en && !fi) {
|
|
4713
|
+
delete promoted[ref];
|
|
4714
|
+
now = false;
|
|
4715
|
+
} else {
|
|
4716
|
+
promoted[ref] = { en, fi };
|
|
4717
|
+
now = true;
|
|
4718
|
+
}
|
|
4719
|
+
return persist().then(function() {
|
|
4720
|
+
return now;
|
|
4721
|
+
});
|
|
4722
|
+
}
|
|
4723
|
+
|
|
4713
4724
|
// src/static/app-catalog/js/monetize.js
|
|
4714
4725
|
var NAME_RE = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
4715
4726
|
var MONEY_UNIT = 1e6;
|
|
@@ -4761,7 +4772,7 @@
|
|
|
4761
4772
|
}
|
|
4762
4773
|
function priceLabel(tool) {
|
|
4763
4774
|
var parts = [];
|
|
4764
|
-
if (tool.price && tool.price.morsels > 0) parts.push(tool.price.morsels + "
|
|
4775
|
+
if (tool.price && tool.price.morsels > 0) parts.push(tool.price.morsels + " morsels");
|
|
4765
4776
|
if (tool.priceMoney && tool.priceMoney.amount > 0) {
|
|
4766
4777
|
parts.push(tool.priceMoney.amount / MONEY_UNIT + " " + tool.priceMoney.currency);
|
|
4767
4778
|
}
|
|
@@ -4902,6 +4913,79 @@
|
|
|
4902
4913
|
});
|
|
4903
4914
|
}
|
|
4904
4915
|
|
|
4916
|
+
// src/static/app-catalog/js/cost.js
|
|
4917
|
+
var cState = "off";
|
|
4918
|
+
var cData = null;
|
|
4919
|
+
var cAppId = "";
|
|
4920
|
+
function apiBase2() {
|
|
4921
|
+
var cfg = loadConfig();
|
|
4922
|
+
return (cfg.aimeatUrl || "").replace(/\/+$/, "");
|
|
4923
|
+
}
|
|
4924
|
+
function rerender2() {
|
|
4925
|
+
var el = document.getElementById("detail-cost");
|
|
4926
|
+
if (el) el.innerHTML = costSectionInner();
|
|
4927
|
+
}
|
|
4928
|
+
function costOnOpen(owner, appId, isOwn) {
|
|
4929
|
+
cData = null;
|
|
4930
|
+
if (!isOwn || !owner || !appId) {
|
|
4931
|
+
cState = "off";
|
|
4932
|
+
cAppId = "";
|
|
4933
|
+
return;
|
|
4934
|
+
}
|
|
4935
|
+
cAppId = owner + "/" + appId;
|
|
4936
|
+
cState = "loading";
|
|
4937
|
+
var token = getCortexOwnerToken();
|
|
4938
|
+
if (!token) {
|
|
4939
|
+
cState = "error";
|
|
4940
|
+
cData = { _needLogin: true };
|
|
4941
|
+
return;
|
|
4942
|
+
}
|
|
4943
|
+
fetch(apiBase2() + "/v1/apps/cost?app_id=" + encodeURIComponent(cAppId), {
|
|
4944
|
+
headers: { "Authorization": "Bearer " + token }
|
|
4945
|
+
}).then(function(r) {
|
|
4946
|
+
return r.json();
|
|
4947
|
+
}).then(function(res) {
|
|
4948
|
+
if (!res || !res.ok || !res.data) throw new Error("bad response");
|
|
4949
|
+
cData = res.data;
|
|
4950
|
+
cState = "ready";
|
|
4951
|
+
rerender2();
|
|
4952
|
+
}).catch(function() {
|
|
4953
|
+
cState = "error";
|
|
4954
|
+
cData = null;
|
|
4955
|
+
rerender2();
|
|
4956
|
+
});
|
|
4957
|
+
}
|
|
4958
|
+
function stateBadge(state) {
|
|
4959
|
+
var cls = state === "active" ? "ok" : state === "paused" ? "diff" : "none";
|
|
4960
|
+
return '<span class="dtl-sync ' + cls + '" style="margin:0">' + escapeHtml(state) + "</span>";
|
|
4961
|
+
}
|
|
4962
|
+
function contractRow(c) {
|
|
4963
|
+
var b = c.budget || {};
|
|
4964
|
+
var cap = b.cap_units === null || b.cap_units === void 0 ? t("cost.uncapped") : b.spent_units + " / " + b.cap_units;
|
|
4965
|
+
var remaining = b.remaining_units === null || b.remaining_units === void 0 ? "" : ' <span class="dtl-stat-label">(' + t("cost.remaining").replace("{n}", b.remaining_units) + ")</span>";
|
|
4966
|
+
var providerShort = String(c.provider || "").split("@")[0];
|
|
4967
|
+
return '<div class="dtl-status-row" style="align-items:center;gap:10px;flex-wrap:wrap"><div class="dtl-stat" style="flex:1;min-width:150px"><span class="dtl-stat-val">' + escapeHtml(c.capability || "") + '</span><span class="dtl-stat-label">' + escapeHtml(t("cost.providerCol")) + ": " + escapeHtml(providerShort) + '</span></div><div class="dtl-stat"><span class="dtl-stat-label">' + t("cost.priceCol") + '</span><span class="dtl-stat-val">' + escapeHtml(String(c.price_per_call)) + ' morsels</span></div><div class="dtl-stat"><span class="dtl-stat-label">' + t("cost.rakeCol") + '</span><span class="dtl-stat-val">' + escapeHtml(String(c.rake_per_call)) + " morsels (" + escapeHtml(String(c.rake_percent)) + '%)</span></div><div class="dtl-stat"><span class="dtl-stat-label">' + t("cost.budgetCol") + '</span><span class="dtl-stat-val">' + escapeHtml(cap) + remaining + '</span></div><div class="dtl-stat">' + stateBadge(c.state) + "</div></div>";
|
|
4968
|
+
}
|
|
4969
|
+
function costSectionInner() {
|
|
4970
|
+
if (cState === "off") return "";
|
|
4971
|
+
var html = "<h3>" + t("cost.title") + '</h3><p class="dtl-desc">' + t("cost.hint") + "</p>";
|
|
4972
|
+
if (cState === "loading") {
|
|
4973
|
+
return html + '<span style="color:var(--text-muted);font-size:.85rem">…</span>';
|
|
4974
|
+
}
|
|
4975
|
+
if (cState === "error") {
|
|
4976
|
+
var msg = cData && cData._needLogin ? t("cost.needLogin") : t("cost.loadFailed");
|
|
4977
|
+
return html + '<span class="dtl-sync none">' + escapeHtml(msg) + "</span>";
|
|
4978
|
+
}
|
|
4979
|
+
var contracts = cData && cData.contracts || [];
|
|
4980
|
+
if (!contracts.length) {
|
|
4981
|
+
return html + '<span class="dtl-sync none">' + t("cost.empty") + "</span>";
|
|
4982
|
+
}
|
|
4983
|
+
var m = cData.totals && cData.totals.morsels || { spent_units: 0, calls: 0 };
|
|
4984
|
+
html += '<div class="dtl-sync ok" style="margin:0 0 10px">' + t("cost.summary").replace("{n}", cData.total_contracts).replace("{spent}", m.spent_units).replace("{calls}", m.calls) + "</div>";
|
|
4985
|
+
for (var i = 0; i < contracts.length; i++) html += contractRow(contracts[i]);
|
|
4986
|
+
return html;
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4905
4989
|
// src/static/app-catalog/js/app-agents.js
|
|
4906
4990
|
var getServerManifests;
|
|
4907
4991
|
function initAppAgents(deps) {
|
|
@@ -4957,8 +5041,8 @@
|
|
|
4957
5041
|
showNotice(t("agents.none"));
|
|
4958
5042
|
return;
|
|
4959
5043
|
}
|
|
4960
|
-
var
|
|
4961
|
-
if (!
|
|
5044
|
+
var base3 = aimeatBase();
|
|
5045
|
+
if (!base3) {
|
|
4962
5046
|
showNotice("Set AIMEAT server URL in Settings first");
|
|
4963
5047
|
return;
|
|
4964
5048
|
}
|
|
@@ -4974,7 +5058,7 @@
|
|
|
4974
5058
|
document.getElementById("agents-overlay").hidden = false;
|
|
4975
5059
|
defs.forEach(function(def2, i2) {
|
|
4976
5060
|
var headers = token ? { "Authorization": "Bearer " + token } : {};
|
|
4977
|
-
fetch(
|
|
5061
|
+
fetch(base3 + "/v1/apps/" + encodeURIComponent(owner) + "/" + encodeURIComponent(filename) + "/agents/" + encodeURIComponent(def2.agent_name) + "/instances", { headers }).then(function(r) {
|
|
4978
5062
|
return r.json();
|
|
4979
5063
|
}).then(function(json) {
|
|
4980
5064
|
var el = document.getElementById("aga-instances-" + i2);
|
|
@@ -4990,7 +5074,7 @@
|
|
|
4990
5074
|
});
|
|
4991
5075
|
});
|
|
4992
5076
|
if (token) {
|
|
4993
|
-
fetch(
|
|
5077
|
+
fetch(base3 + "/v1/agents", { headers: { "Authorization": "Bearer " + token } }).then(function(r) {
|
|
4994
5078
|
return r.json();
|
|
4995
5079
|
}).then(function(json) {
|
|
4996
5080
|
var agents = json.data && json.data.agents || [];
|
|
@@ -5017,7 +5101,7 @@
|
|
|
5017
5101
|
} catch (e) {
|
|
5018
5102
|
}
|
|
5019
5103
|
if (me) {
|
|
5020
|
-
fetch(
|
|
5104
|
+
fetch(base3 + "/v1/organisms?member=" + encodeURIComponent(me), { headers: { "Authorization": "Bearer " + token } }).then(function(r) {
|
|
5021
5105
|
return r.json();
|
|
5022
5106
|
}).then(function(json) {
|
|
5023
5107
|
var orgs = json.data && json.data.organisms || [];
|
|
@@ -5169,6 +5253,7 @@
|
|
|
5169
5253
|
var app = detailGetApp();
|
|
5170
5254
|
if (!app) return;
|
|
5171
5255
|
monetizeOnOpen(detailServerOwner(app), app.publishedFilename || "", detailIsOwnPublished(app));
|
|
5256
|
+
costOnOpen(detailServerOwner(app), app.publishedFilename || "", detailIsOwnPublished(app));
|
|
5172
5257
|
document.getElementById("detail-view").hidden = false;
|
|
5173
5258
|
renderDetailView();
|
|
5174
5259
|
detailCheckAiAvailability();
|
|
@@ -5195,14 +5280,14 @@
|
|
|
5195
5280
|
var app = detailGetApp();
|
|
5196
5281
|
if (!app) return;
|
|
5197
5282
|
if (app.published && (app.publishedUrl || app.publishedFilename)) {
|
|
5198
|
-
var
|
|
5283
|
+
var base3 = (loadConfig().aimeatUrl || "").replace(/\/+$/, "");
|
|
5199
5284
|
var url;
|
|
5200
5285
|
if (app.publishedUrl) {
|
|
5201
|
-
url =
|
|
5286
|
+
url = base3 + app.publishedUrl;
|
|
5202
5287
|
} else {
|
|
5203
5288
|
var st = getServerState()[app.publishedFilename] || {};
|
|
5204
5289
|
var owner = st.owner || currentOwnerName() || "";
|
|
5205
|
-
url =
|
|
5290
|
+
url = base3 + "/v1/apps/" + encodeURIComponent(owner) + "/" + encodeURIComponent(app.publishedFilename);
|
|
5206
5291
|
}
|
|
5207
5292
|
viewPublished(url + "?mode=inline", app.name);
|
|
5208
5293
|
} else {
|
|
@@ -5224,11 +5309,6 @@
|
|
|
5224
5309
|
});
|
|
5225
5310
|
}
|
|
5226
5311
|
function onAuthChanged() {
|
|
5227
|
-
if (getDbMode() === "personal" && !currentOwnerName()) {
|
|
5228
|
-
setDbMode("global");
|
|
5229
|
-
}
|
|
5230
|
-
closeDbInstance();
|
|
5231
|
-
updateModeToggle();
|
|
5232
5312
|
try {
|
|
5233
5313
|
refreshAll();
|
|
5234
5314
|
} catch (e) {
|
|
@@ -5310,13 +5390,17 @@
|
|
|
5310
5390
|
var tags = app.tags && app.tags.length ? app.tags.join(", ") : "—";
|
|
5311
5391
|
var cortex = app.usesCortex && app.usesCortex.length ? app.usesCortex.join(", ") : "—";
|
|
5312
5392
|
var created = app.addedAt ? new Date(app.addedAt).toLocaleString() : "—";
|
|
5313
|
-
var favBtn =
|
|
5393
|
+
var favBtn = "";
|
|
5314
5394
|
var aboutHeader = '<h3 style="display:flex;align-items:center;justify-content:space-between;gap:8px"><span>' + t("detail.about") + '</span><span style="display:flex;align-items:center;gap:8px">' + favBtn + (canEditAbout && !detailEditingAbout ? dtlBtn(t("detail.editDetails"), "window._launcher.detailAboutEdit()") : "") + "</span></h3>";
|
|
5395
|
+
var descs = app.descriptions || {};
|
|
5396
|
+
var descEnVal = descs.en || (app.description || "");
|
|
5397
|
+
var descFiVal = descs.fi || "";
|
|
5315
5398
|
var aboutBody;
|
|
5316
5399
|
if (detailEditingAbout) {
|
|
5317
|
-
aboutBody = '<label class="dtl-stat-label" for="detail-name-input">' + t("detail.nameLabel") + '</label><input id="detail-name-input" class="modal-input" maxlength="120" value="' + escapeHtml(app.name || "") + '" style="margin:4px 0 10px" /><label class="dtl-stat-label" for="detail-desc-
|
|
5400
|
+
aboutBody = '<label class="dtl-stat-label" for="detail-name-input">' + t("detail.nameLabel") + '</label><input id="detail-name-input" class="modal-input" maxlength="120" value="' + escapeHtml(app.name || "") + '" style="margin:4px 0 10px" /><label class="dtl-stat-label" for="detail-desc-en">' + t("detail.descEn") + '</label><textarea id="detail-desc-en" class="modal-input" rows="3" maxlength="2000" style="margin:4px 0 6px;resize:vertical">' + escapeHtml(descEnVal) + '</textarea><label class="dtl-stat-label" for="detail-desc-fi">' + t("detail.descFi") + '</label><textarea id="detail-desc-fi" class="modal-input" rows="3" maxlength="2000" style="margin:4px 0 6px;resize:vertical">' + escapeHtml(descFiVal) + '</textarea><div class="dtl-btn-row" style="margin:0 0 4px">' + dtlBtn("🌐 " + t("detail.translateEnFi"), "window._launcher.detailTranslateDesc('en','fi')", { id: "detail-tr-enfi" }) + dtlBtn("🌐 " + t("detail.translateFiEn"), "window._launcher.detailTranslateDesc('fi','en')", { id: "detail-tr-fien" }) + '</div><div class="dtl-ai-status" id="detail-tr-status" style="margin:0 0 8px"></div><label class="dtl-stat-label" for="detail-icon-input">' + t("detail.iconLabel") + '</label><input id="detail-icon-input" class="modal-input" maxlength="4" value="' + escapeHtml(app.icon || "") + '" style="margin:4px 0 10px;text-align:center;font-size:1.2rem" /><label class="dtl-stat-label" for="detail-tags-input">' + t("detail.tagsLabel") + '</label><input id="detail-tags-input" class="modal-input" value="' + escapeHtml((app.tags || []).join(", ")) + '" placeholder="tools, productivity" style="margin:4px 0 8px" /><div class="dtl-sync none" style="margin:0 0 10px">' + t("detail.renameHint") + '</div><div class="dtl-btn-row">' + dtlBtn(t("detail.saveDetails"), "window._launcher.detailAboutSave()", { variant: "primary" }) + dtlBtn(t("detail.cancelEdit"), "window._launcher.detailAboutCancel()") + "</div>";
|
|
5318
5401
|
} else {
|
|
5319
|
-
|
|
5402
|
+
var shownDesc = app.descriptions && app.descriptions[getLang()] || app.description || "";
|
|
5403
|
+
aboutBody = (shownDesc ? '<p class="dtl-desc">' + escapeHtml(shownDesc) + "</p>" : "") + '<div class="dtl-meta-grid">' + metaItem(t("detail.category"), app.category || "utility") + metaItem(t("detail.tags"), tags) + metaItem(t("detail.sourceLabel"), sourceLabelText(app.source)) + metaItem(t("detail.size"), app.blob ? fmtSize(localBytes) : "—") + metaItem(t("detail.created"), created) + metaItem(t("detail.usesCortex"), cortex) + // Provenance: if this app was forked from another, credit the source app.
|
|
5320
5404
|
(app.forkedFrom && app.forkedFrom.owner && app.forkedFrom.filename ? metaItem(t("detail.forkedFrom"), app.forkedFrom.owner + "/" + app.forkedFrom.filename + (app.forkedFrom.version ? " v" + app.forkedFrom.version : "")) : "") + "</div>";
|
|
5321
5405
|
}
|
|
5322
5406
|
var aboutHtml = '<div class="dtl-section">' + aboutHeader + aboutBody + "</div>";
|
|
@@ -5342,6 +5426,8 @@
|
|
|
5342
5426
|
(ownPub ? '<div id="detail-skill-attach" style="margin-top:8px">' + detailSkillAttachInner() + "</div>" : "") + "</div>";
|
|
5343
5427
|
}
|
|
5344
5428
|
var monetizeHtml = app.published && detailIsOwnPublished(app) ? '<div class="dtl-section" id="detail-monetize">' + monetizeSectionInner() + "</div>" : "";
|
|
5429
|
+
var costHtml = app.published && detailIsOwnPublished(app) ? '<div class="dtl-section" id="detail-cost">' + costSectionInner() + "</div>" : "";
|
|
5430
|
+
var promoteHtml = app.published && detailIsOwnPublished(app) ? buildPromoteSection(app) : "";
|
|
5345
5431
|
var agentsHtml = "";
|
|
5346
5432
|
if (app.published) {
|
|
5347
5433
|
var agOwner = detailServerOwner(app);
|
|
@@ -5356,7 +5442,43 @@
|
|
|
5356
5442
|
) + "</div>";
|
|
5357
5443
|
}
|
|
5358
5444
|
}
|
|
5359
|
-
document.getElementById("detail-body").innerHTML = statusHtml + aboutHtml + aiHtml + versionsHtml + skillsHtml + agentsHtml + monetizeHtml + mgmtHtml + actionsHtml;
|
|
5445
|
+
document.getElementById("detail-body").innerHTML = statusHtml + aboutHtml + aiHtml + versionsHtml + skillsHtml + agentsHtml + monetizeHtml + costHtml + promoteHtml + mgmtHtml + actionsHtml;
|
|
5446
|
+
}
|
|
5447
|
+
function promoteRef(app) {
|
|
5448
|
+
return detailServerOwner(app) + "/" + (app.publishedFilename || "");
|
|
5449
|
+
}
|
|
5450
|
+
function buildPromoteSection(app) {
|
|
5451
|
+
var ref = promoteRef(app);
|
|
5452
|
+
var cur = getPromotion(ref) || {};
|
|
5453
|
+
var on = !!(cur.en || cur.fi);
|
|
5454
|
+
return '<div class="dtl-section" id="detail-promote"><h3 style="display:flex;align-items:center;gap:8px">📣 ' + t("promote.title") + (on ? ' <span class="dtl-badge-on">' + t("promote.on") + "</span>" : "") + '</h3><p class="dtl-desc">' + t("promote.hint") + '</p><label class="dtl-stat-label" for="detail-promo-en">' + t("promote.en") + '</label><textarea id="detail-promo-en" class="modal-input" rows="2" maxlength="500" style="margin:4px 0 6px;resize:vertical">' + escapeHtml(cur.en || "") + '</textarea><label class="dtl-stat-label" for="detail-promo-fi">' + t("promote.fi") + '</label><textarea id="detail-promo-fi" class="modal-input" rows="2" maxlength="500" style="margin:4px 0 6px;resize:vertical">' + escapeHtml(cur.fi || "") + '</textarea><div class="dtl-btn-row" style="margin:0 0 4px">' + dtlBtn("🌐 " + t("detail.translateEnFi"), "window._launcher.detailTranslateDesc('en','fi','detail-promo-','detail-promo-tr-status')") + dtlBtn("🌐 " + t("detail.translateFiEn"), "window._launcher.detailTranslateDesc('fi','en','detail-promo-','detail-promo-tr-status')") + '</div><div class="dtl-ai-status" id="detail-promo-tr-status" style="margin:0 0 8px"></div><div class="dtl-btn-row">' + dtlBtn(t("promote.save"), "window._launcher.detailPromoteSave()", { variant: "primary" }) + (on ? dtlBtn(t("promote.remove"), "window._launcher.detailPromoteClear()") : "") + '</div><div class="dtl-ai-status" id="detail-promo-status"></div></div>';
|
|
5455
|
+
}
|
|
5456
|
+
function detailPromoteSave() {
|
|
5457
|
+
var app = detailGetApp();
|
|
5458
|
+
if (!app || !detailIsOwnPublished(app)) return;
|
|
5459
|
+
var en = (document.getElementById("detail-promo-en") || {}).value || "";
|
|
5460
|
+
var fi = (document.getElementById("detail-promo-fi") || {}).value || "";
|
|
5461
|
+
var statusEl = document.getElementById("detail-promo-status");
|
|
5462
|
+
if (statusEl) {
|
|
5463
|
+
statusEl.style.color = "var(--text-muted)";
|
|
5464
|
+
statusEl.textContent = t("promote.saving");
|
|
5465
|
+
}
|
|
5466
|
+
setPromotion(promoteRef(app), { en, fi }).then(function(nowOn) {
|
|
5467
|
+
renderApps();
|
|
5468
|
+
renderDetailView();
|
|
5469
|
+
var s2 = document.getElementById("detail-promo-status");
|
|
5470
|
+
if (s2) {
|
|
5471
|
+
s2.style.color = "#34d399";
|
|
5472
|
+
s2.textContent = nowOn ? "✔ " + t("promote.saved") : "✔ " + t("promote.removed");
|
|
5473
|
+
}
|
|
5474
|
+
});
|
|
5475
|
+
}
|
|
5476
|
+
function detailPromoteClear() {
|
|
5477
|
+
var en = document.getElementById("detail-promo-en");
|
|
5478
|
+
if (en) en.value = "";
|
|
5479
|
+
var fi = document.getElementById("detail-promo-fi");
|
|
5480
|
+
if (fi) fi.value = "";
|
|
5481
|
+
detailPromoteSave();
|
|
5360
5482
|
}
|
|
5361
5483
|
function detailLoadSkills(owner, filename) {
|
|
5362
5484
|
var config = loadConfig();
|
|
@@ -5568,27 +5690,27 @@
|
|
|
5568
5690
|
return h;
|
|
5569
5691
|
}
|
|
5570
5692
|
function skillListMine() {
|
|
5571
|
-
var
|
|
5572
|
-
if (!
|
|
5573
|
-
return fetch(
|
|
5693
|
+
var base3 = skillApiBase();
|
|
5694
|
+
if (!base3) return Promise.reject(new Error("No server configured"));
|
|
5695
|
+
return fetch(base3 + "/v1/skills?scope=user", { headers: skillAuthHeaders(false) }).then(function(r) {
|
|
5574
5696
|
return r.json();
|
|
5575
5697
|
}).then(function(j) {
|
|
5576
5698
|
return j.data && j.data.skills ? j.data.skills : [];
|
|
5577
5699
|
});
|
|
5578
5700
|
}
|
|
5579
5701
|
function skillGetMine(name) {
|
|
5580
|
-
var
|
|
5581
|
-
return fetch(
|
|
5702
|
+
var base3 = skillApiBase();
|
|
5703
|
+
return fetch(base3 + "/v1/skills/" + encodeURIComponent(name) + "?scope=user", { headers: skillAuthHeaders(false) }).then(function(r) {
|
|
5582
5704
|
return r.json();
|
|
5583
5705
|
}).then(function(j) {
|
|
5584
5706
|
return j.data && j.data.skill || null;
|
|
5585
5707
|
});
|
|
5586
5708
|
}
|
|
5587
5709
|
function skillPublish(skillMd, files) {
|
|
5588
|
-
var
|
|
5710
|
+
var base3 = skillApiBase();
|
|
5589
5711
|
var body = { skill_md: skillMd };
|
|
5590
5712
|
if (files && Object.keys(files).length) body.files = files;
|
|
5591
|
-
return fetch(
|
|
5713
|
+
return fetch(base3 + "/v1/skills", { method: "POST", headers: skillAuthHeaders(true), body: JSON.stringify(body) }).then(function(r) {
|
|
5592
5714
|
return r.json().then(function(j) {
|
|
5593
5715
|
if (!j.ok) throw new Error(j.error && (j.error.message || j.error.code) || "HTTP " + r.status);
|
|
5594
5716
|
return j.data && j.data.skill || null;
|
|
@@ -5646,11 +5768,17 @@
|
|
|
5646
5768
|
var app = detailGetApp();
|
|
5647
5769
|
if (!app) return;
|
|
5648
5770
|
var nameEl = document.getElementById("detail-name-input");
|
|
5649
|
-
var
|
|
5771
|
+
var enEl = document.getElementById("detail-desc-en");
|
|
5772
|
+
var fiEl = document.getElementById("detail-desc-fi");
|
|
5650
5773
|
var iconEl = document.getElementById("detail-icon-input");
|
|
5651
5774
|
var tagsEl = document.getElementById("detail-tags-input");
|
|
5652
5775
|
var newName = nameEl ? nameEl.value.trim() : "";
|
|
5653
|
-
var
|
|
5776
|
+
var enDesc = enEl ? enEl.value.trim() : "";
|
|
5777
|
+
var fiDesc = fiEl ? fiEl.value.trim() : "";
|
|
5778
|
+
var newDescriptions = {};
|
|
5779
|
+
if (enDesc) newDescriptions.en = enDesc;
|
|
5780
|
+
if (fiDesc) newDescriptions.fi = fiDesc;
|
|
5781
|
+
var newDesc = enDesc || fiDesc || "";
|
|
5654
5782
|
var newIcon = iconEl ? iconEl.value.trim() : app.icon || "";
|
|
5655
5783
|
var newTags = tagsEl ? tagsEl.value.split(",").map(function(s) {
|
|
5656
5784
|
return s.trim();
|
|
@@ -5662,12 +5790,13 @@
|
|
|
5662
5790
|
}
|
|
5663
5791
|
if (app.published && !newDesc) {
|
|
5664
5792
|
showNotice(t("detail.descRequired") || "Description cannot be empty.");
|
|
5665
|
-
if (
|
|
5793
|
+
if (enEl) enEl.focus();
|
|
5666
5794
|
return;
|
|
5667
5795
|
}
|
|
5668
5796
|
function finishLocal() {
|
|
5669
5797
|
app.name = newName;
|
|
5670
5798
|
app.description = newDesc;
|
|
5799
|
+
app.descriptions = newDescriptions;
|
|
5671
5800
|
app.icon = newIcon;
|
|
5672
5801
|
app.tags = newTags;
|
|
5673
5802
|
saveApp(app).then(function() {
|
|
@@ -5693,7 +5822,7 @@
|
|
|
5693
5822
|
fetch(aimeatUrl + "/v1/apps/" + encodeURIComponent(filename), {
|
|
5694
5823
|
method: "PATCH",
|
|
5695
5824
|
headers: { "Authorization": "Bearer " + token, "Content-Type": "application/json" },
|
|
5696
|
-
body: JSON.stringify({ name: newName, description: newDesc })
|
|
5825
|
+
body: JSON.stringify({ name: newName, description: newDesc, descriptions: newDescriptions })
|
|
5697
5826
|
}).then(function(resp) {
|
|
5698
5827
|
return resp.json().then(function(j) {
|
|
5699
5828
|
return { ok: resp.ok, j };
|
|
@@ -5704,6 +5833,7 @@
|
|
|
5704
5833
|
getServerManifests2()[key] = getServerManifests2()[key] || {};
|
|
5705
5834
|
getServerManifests2()[key].name = newName;
|
|
5706
5835
|
getServerManifests2()[key].description = newDesc;
|
|
5836
|
+
getServerManifests2()[key].descriptions = newDescriptions;
|
|
5707
5837
|
finishLocal();
|
|
5708
5838
|
} else {
|
|
5709
5839
|
showNotice("Failed: " + (res.j && res.j.error && res.j.error.message || "Unknown error"));
|
|
@@ -5712,6 +5842,69 @@
|
|
|
5712
5842
|
showNotice("Error: " + (err.message || err));
|
|
5713
5843
|
});
|
|
5714
5844
|
}
|
|
5845
|
+
function detailTranslateDesc(srcLang, dstLang, prefix, statusId) {
|
|
5846
|
+
prefix = prefix || "detail-desc-";
|
|
5847
|
+
var srcEl = document.getElementById(prefix + srcLang);
|
|
5848
|
+
var dstEl = document.getElementById(prefix + dstLang);
|
|
5849
|
+
var statusEl = document.getElementById(statusId || "detail-tr-status");
|
|
5850
|
+
if (!srcEl || !dstEl) return;
|
|
5851
|
+
var text = (srcEl.value || "").trim();
|
|
5852
|
+
if (!text) {
|
|
5853
|
+
if (statusEl) statusEl.textContent = t("detail.trNeedSource");
|
|
5854
|
+
return;
|
|
5855
|
+
}
|
|
5856
|
+
var token = getCortexOwnerToken2();
|
|
5857
|
+
if (!token) {
|
|
5858
|
+
if (statusEl) statusEl.textContent = t("detail.aiLoginNeeded");
|
|
5859
|
+
return;
|
|
5860
|
+
}
|
|
5861
|
+
var config = loadConfig();
|
|
5862
|
+
var aimeatUrl = (config.aimeatUrl || "").replace(/\/+$/, "");
|
|
5863
|
+
if (!aimeatUrl) {
|
|
5864
|
+
if (statusEl) statusEl.textContent = t("detail.aiUnavailable");
|
|
5865
|
+
return;
|
|
5866
|
+
}
|
|
5867
|
+
var langName = { en: "English", fi: "Finnish" };
|
|
5868
|
+
if (statusEl) {
|
|
5869
|
+
statusEl.style.color = "var(--text-muted)";
|
|
5870
|
+
statusEl.textContent = t("detail.translating");
|
|
5871
|
+
}
|
|
5872
|
+
var systemPrompt = "You are a professional translator for short app-store copy. Translate the text from " + (langName[srcLang] || srcLang) + " to " + (langName[dstLang] || dstLang) + ". Return ONLY the translated text — no quotes, no notes, no explanation. Keep it concise and natural.";
|
|
5873
|
+
fetch(aimeatUrl + "/v1/ai/complete", {
|
|
5874
|
+
method: "POST",
|
|
5875
|
+
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
|
|
5876
|
+
body: JSON.stringify({ prompt: text, systemPrompt, app_id: "app-catalog" })
|
|
5877
|
+
}).then(function(resp) {
|
|
5878
|
+
return resp.json();
|
|
5879
|
+
}).then(function(json) {
|
|
5880
|
+
if (!json || !json.ok) {
|
|
5881
|
+
var msg = json && json.error && json.error.message || "Translation failed";
|
|
5882
|
+
if (statusEl) {
|
|
5883
|
+
statusEl.style.color = "var(--accent)";
|
|
5884
|
+
statusEl.textContent = "✘ " + msg;
|
|
5885
|
+
}
|
|
5886
|
+
return;
|
|
5887
|
+
}
|
|
5888
|
+
var out = (json.data && json.data.content ? json.data.content : "").trim();
|
|
5889
|
+
if (!out) {
|
|
5890
|
+
if (statusEl) {
|
|
5891
|
+
statusEl.style.color = "var(--accent)";
|
|
5892
|
+
statusEl.textContent = "✘ " + t("detail.trEmpty");
|
|
5893
|
+
}
|
|
5894
|
+
return;
|
|
5895
|
+
}
|
|
5896
|
+
dstEl.value = out;
|
|
5897
|
+
if (statusEl) {
|
|
5898
|
+
statusEl.style.color = "#34d399";
|
|
5899
|
+
statusEl.textContent = "✔ " + t("detail.trDone");
|
|
5900
|
+
}
|
|
5901
|
+
}).catch(function(err) {
|
|
5902
|
+
if (statusEl) {
|
|
5903
|
+
statusEl.style.color = "var(--accent)";
|
|
5904
|
+
statusEl.textContent = "✘ " + (err.message || "Translation failed");
|
|
5905
|
+
}
|
|
5906
|
+
});
|
|
5907
|
+
}
|
|
5715
5908
|
function detailSetScreenshot() {
|
|
5716
5909
|
var app = detailGetApp();
|
|
5717
5910
|
if (!app) return;
|
|
@@ -6004,9 +6197,9 @@
|
|
|
6004
6197
|
function draftApi(method, owner, filename, sub, body) {
|
|
6005
6198
|
var cfg = loadConfig();
|
|
6006
6199
|
if (!cfg.aimeatUrl) return Promise.reject(new Error("Set the AIMEAT server URL in Settings first"));
|
|
6007
|
-
var
|
|
6200
|
+
var base3 = cfg.aimeatUrl.replace(/\/+$/, "");
|
|
6008
6201
|
var path = "/v1/apps/" + encodeURIComponent(owner) + "/" + encodeURIComponent(filename) + "/" + sub;
|
|
6009
|
-
return fetch(
|
|
6202
|
+
return fetch(base3 + path, {
|
|
6010
6203
|
method,
|
|
6011
6204
|
headers: { "Authorization": "Bearer " + getCortexOwnerToken2(), "Content-Type": "application/json" },
|
|
6012
6205
|
body: body ? JSON.stringify(body) : void 0
|
|
@@ -6196,6 +6389,7 @@
|
|
|
6196
6389
|
id: generateId2(),
|
|
6197
6390
|
name: meta.name || filename.replace(/\.html?$/i, ""),
|
|
6198
6391
|
description: meta.description || "",
|
|
6392
|
+
descriptions: meta.descriptions || null,
|
|
6199
6393
|
category: meta.category || "utility",
|
|
6200
6394
|
tags: meta.tags || [],
|
|
6201
6395
|
usesCortex: meta.usesCortex || [],
|
|
@@ -6429,6 +6623,7 @@
|
|
|
6429
6623
|
mime_type: "text/html",
|
|
6430
6624
|
name: meta.name || filename.replace(/\.html?$/i, ""),
|
|
6431
6625
|
description: meta.description || "",
|
|
6626
|
+
descriptions: meta.descriptions || null,
|
|
6432
6627
|
category: meta.category || "utility",
|
|
6433
6628
|
tags: meta.tags || [],
|
|
6434
6629
|
uses_cortex: meta.usesCortex || []
|
|
@@ -6464,8 +6659,8 @@
|
|
|
6464
6659
|
showNotice(t("common.loginRequired") || "You must be logged in to fork an app into your own catalogue. Sign in first.");
|
|
6465
6660
|
return;
|
|
6466
6661
|
}
|
|
6467
|
-
var
|
|
6468
|
-
var suggested =
|
|
6662
|
+
var base3 = (filename || "app").replace(/\.html?$/i, "");
|
|
6663
|
+
var suggested = base3 + "-fork.html";
|
|
6469
6664
|
var newName = prompt(t("fork.prompt") || 'Fork "' + filename + '" into a new app.\n\nNew filename:', suggested);
|
|
6470
6665
|
if (!newName) return;
|
|
6471
6666
|
newName = newName.trim();
|
|
@@ -6514,11 +6709,7 @@
|
|
|
6514
6709
|
}
|
|
6515
6710
|
|
|
6516
6711
|
// src/static/app-catalog/js/settings.js
|
|
6517
|
-
|
|
6518
|
-
var renderApps2;
|
|
6519
|
-
var loadPublishedApps2;
|
|
6520
|
-
function initSettings(deps) {
|
|
6521
|
-
({ generateId: generateId3, renderApps: renderApps2, loadPublishedApps: loadPublishedApps2 } = deps);
|
|
6712
|
+
function initSettings() {
|
|
6522
6713
|
}
|
|
6523
6714
|
function applyTheme(theme) {
|
|
6524
6715
|
if (theme === "dark") {
|
|
@@ -6665,260 +6856,36 @@
|
|
|
6665
6856
|
function closeHelp() {
|
|
6666
6857
|
document.getElementById("help-overlay").hidden = true;
|
|
6667
6858
|
}
|
|
6668
|
-
function exportBackup() {
|
|
6669
|
-
getAllApps().then(function(apps) {
|
|
6670
|
-
var config = loadConfig();
|
|
6671
|
-
var backup = {
|
|
6672
|
-
version: 1,
|
|
6673
|
-
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6674
|
-
config,
|
|
6675
|
-
apps
|
|
6676
|
-
};
|
|
6677
|
-
var json = JSON.stringify(backup, null, 2);
|
|
6678
|
-
var blob = new Blob([json], { type: "application/json" });
|
|
6679
|
-
var url = URL.createObjectURL(blob);
|
|
6680
|
-
var a = document.createElement("a");
|
|
6681
|
-
a.href = url;
|
|
6682
|
-
a.download = "app-catalog-backup-" + (/* @__PURE__ */ new Date()).toISOString().slice(0, 10) + ".json";
|
|
6683
|
-
document.body.appendChild(a);
|
|
6684
|
-
a.click();
|
|
6685
|
-
document.body.removeChild(a);
|
|
6686
|
-
URL.revokeObjectURL(url);
|
|
6687
|
-
});
|
|
6688
|
-
}
|
|
6689
|
-
function localAppKey(a) {
|
|
6690
|
-
if (a.publishedFilename) return "pf:" + a.publishedFilename;
|
|
6691
|
-
return "nm:" + (a.name || "") + "|" + (a.blob ? a.blob.length : a.url || "");
|
|
6692
|
-
}
|
|
6693
|
-
var jsonImportState = null;
|
|
6694
|
-
function handleImportBackup(file) {
|
|
6695
|
-
if (!file) return;
|
|
6696
|
-
var reader = new FileReader();
|
|
6697
|
-
reader.onload = function() {
|
|
6698
|
-
var backup;
|
|
6699
|
-
try {
|
|
6700
|
-
backup = JSON.parse(reader.result);
|
|
6701
|
-
} catch (e) {
|
|
6702
|
-
showNotice("Failed to parse backup file: " + (e.message || e));
|
|
6703
|
-
return;
|
|
6704
|
-
}
|
|
6705
|
-
if (!backup.apps || !Array.isArray(backup.apps)) {
|
|
6706
|
-
showNotice("Invalid backup file: missing apps array");
|
|
6707
|
-
return;
|
|
6708
|
-
}
|
|
6709
|
-
getAllApps().then(function(existing) {
|
|
6710
|
-
var existingKeys = {};
|
|
6711
|
-
existing.forEach(function(a) {
|
|
6712
|
-
existingKeys[localAppKey(a)] = true;
|
|
6713
|
-
});
|
|
6714
|
-
jsonImportState = {
|
|
6715
|
-
backup,
|
|
6716
|
-
rows: backup.apps.map(function(a) {
|
|
6717
|
-
return { app: a, isDup: !!existingKeys[localAppKey(a)] };
|
|
6718
|
-
})
|
|
6719
|
-
};
|
|
6720
|
-
renderJsonImportModal();
|
|
6721
|
-
});
|
|
6722
|
-
};
|
|
6723
|
-
reader.readAsText(file);
|
|
6724
|
-
}
|
|
6725
|
-
function renderJsonImportModal() {
|
|
6726
|
-
var rows = jsonImportState.rows;
|
|
6727
|
-
var body = document.getElementById("json-import-body");
|
|
6728
|
-
var html = '<p style="font-size:.8rem;color:var(--text-muted);margin:4px 0 8px">' + t("jsonImport.desc") + '</p><div class="backup-toolbar-row"><div><button class="backup-link-btn" onclick="window._launcher.jsonImportSelectAll(true)">' + t("backup.selectAll") + '</button> / <button class="backup-link-btn" onclick="window._launcher.jsonImportSelectAll(false)">' + t("backup.selectNone") + '</button></div></div><table class="backup-table"><tbody>';
|
|
6729
|
-
for (var i = 0; i < rows.length; i++) {
|
|
6730
|
-
var a = rows[i].app;
|
|
6731
|
-
html += '<tr><td><input type="checkbox" class="json-import-cb" data-i="' + i + '"' + (rows[i].isDup ? "" : " checked") + "/></td><td>" + escapeHtml(a.name || a.publishedFilename || "Untitled") + (a.publishedFilename ? '<div class="mono-cell">' + escapeHtml(a.publishedFilename) + "</div>" : "") + "</td><td>" + sourceLabel(a.source) + "</td><td>" + (rows[i].isDup ? '<span class="backup-status-badge backup-status-exists">' + t("jsonImport.statusDup") + "</span>" : '<span class="backup-status-badge backup-status-new">' + t("backup.statusNew") + "</span>") + "</td></tr>";
|
|
6732
|
-
}
|
|
6733
|
-
html += "</tbody></table>";
|
|
6734
|
-
if (jsonImportState.backup.config && typeof jsonImportState.backup.config === "object") {
|
|
6735
|
-
html += '<label style="display:flex;align-items:center;gap:8px;margin-top:10px;font-size:.85rem"><input type="checkbox" id="json-import-config"/> ' + t("jsonImport.config") + "</label>";
|
|
6736
|
-
}
|
|
6737
|
-
body.innerHTML = html;
|
|
6738
|
-
document.getElementById("json-import-status").textContent = "";
|
|
6739
|
-
document.getElementById("json-import-btn").style.display = "";
|
|
6740
|
-
document.getElementById("json-import-overlay").hidden = false;
|
|
6741
|
-
}
|
|
6742
|
-
function jsonImportSelectAll(checked) {
|
|
6743
|
-
document.querySelectorAll(".json-import-cb").forEach(function(b) {
|
|
6744
|
-
b.checked = checked;
|
|
6745
|
-
});
|
|
6746
|
-
}
|
|
6747
|
-
function submitJsonImport() {
|
|
6748
|
-
var statusEl = document.getElementById("json-import-status");
|
|
6749
|
-
var selected = [];
|
|
6750
|
-
document.querySelectorAll(".json-import-cb").forEach(function(b) {
|
|
6751
|
-
if (b.checked) selected.push(jsonImportState.rows[parseInt(b.getAttribute("data-i"), 10)].app);
|
|
6752
|
-
});
|
|
6753
|
-
var configCb = document.getElementById("json-import-config");
|
|
6754
|
-
var importConfig = !!(configCb && configCb.checked);
|
|
6755
|
-
if (selected.length === 0 && !importConfig) {
|
|
6756
|
-
statusEl.style.color = "#ef4444";
|
|
6757
|
-
statusEl.textContent = t("backup.nothingSelected");
|
|
6758
|
-
return;
|
|
6759
|
-
}
|
|
6760
|
-
if (importConfig) {
|
|
6761
|
-
var merged = Object.assign({}, loadConfig(), jsonImportState.backup.config);
|
|
6762
|
-
saveConfig(merged);
|
|
6763
|
-
applyTheme(merged.theme);
|
|
6764
|
-
}
|
|
6765
|
-
Promise.all(selected.map(function(a) {
|
|
6766
|
-
var app = Object.assign({}, a);
|
|
6767
|
-
app.id = generateId3();
|
|
6768
|
-
return saveApp(app);
|
|
6769
|
-
})).then(function() {
|
|
6770
|
-
statusEl.style.color = "#34d399";
|
|
6771
|
-
statusEl.textContent = "✔ " + t("jsonImport.done") + ": " + selected.length;
|
|
6772
|
-
document.getElementById("json-import-btn").style.display = "none";
|
|
6773
|
-
renderApps2();
|
|
6774
|
-
loadPublishedApps2();
|
|
6775
|
-
});
|
|
6776
|
-
}
|
|
6777
|
-
function removeDuplicateApps() {
|
|
6778
|
-
getAllApps().then(async function(apps) {
|
|
6779
|
-
var groups = {};
|
|
6780
|
-
apps.forEach(function(a) {
|
|
6781
|
-
var k = localAppKey(a);
|
|
6782
|
-
(groups[k] = groups[k] || []).push(a);
|
|
6783
|
-
});
|
|
6784
|
-
var toDelete = [];
|
|
6785
|
-
Object.keys(groups).forEach(function(k) {
|
|
6786
|
-
var g = groups[k];
|
|
6787
|
-
if (g.length < 2) return;
|
|
6788
|
-
g.sort(function(x, y) {
|
|
6789
|
-
if (!!y.favorite !== !!x.favorite) return (y.favorite ? 1 : 0) - (x.favorite ? 1 : 0);
|
|
6790
|
-
return (x.addedAt || "") < (y.addedAt || "") ? -1 : 1;
|
|
6791
|
-
});
|
|
6792
|
-
toDelete = toDelete.concat(g.slice(1));
|
|
6793
|
-
});
|
|
6794
|
-
if (toDelete.length === 0) {
|
|
6795
|
-
showNotice(t("dedup.none"));
|
|
6796
|
-
return;
|
|
6797
|
-
}
|
|
6798
|
-
if (!await showConfirm(t("dedup.confirm") + " " + toDelete.length)) return;
|
|
6799
|
-
Promise.all(toDelete.map(function(a) {
|
|
6800
|
-
return deleteApp(a.id);
|
|
6801
|
-
})).then(function() {
|
|
6802
|
-
renderApps2();
|
|
6803
|
-
loadPublishedApps2();
|
|
6804
|
-
showNotice(t("dedup.done") + ": " + toDelete.length);
|
|
6805
|
-
});
|
|
6806
|
-
});
|
|
6807
|
-
}
|
|
6808
|
-
async function clearAllData() {
|
|
6809
|
-
if (!await showConfirm(t("confirm.clearAll1"))) return;
|
|
6810
|
-
if (!await showConfirm(t("confirm.clearAll2"))) return;
|
|
6811
|
-
openDB().then(function(db) {
|
|
6812
|
-
return new Promise(function(resolve, reject) {
|
|
6813
|
-
var tx = db.transaction(STORE_NAME, "readwrite");
|
|
6814
|
-
tx.objectStore(STORE_NAME).clear();
|
|
6815
|
-
tx.oncomplete = function() {
|
|
6816
|
-
resolve();
|
|
6817
|
-
};
|
|
6818
|
-
tx.onerror = function() {
|
|
6819
|
-
reject(tx.error);
|
|
6820
|
-
};
|
|
6821
|
-
});
|
|
6822
|
-
}).then(function() {
|
|
6823
|
-
localStorage.removeItem("appLauncherConfig");
|
|
6824
|
-
applyTheme("dark");
|
|
6825
|
-
renderApps2();
|
|
6826
|
-
document.getElementById("settings-overlay").hidden = true;
|
|
6827
|
-
showNotice("All data cleared");
|
|
6828
|
-
});
|
|
6829
|
-
}
|
|
6830
6859
|
|
|
6831
6860
|
// src/static/app-catalog/js/apps-io.js
|
|
6832
|
-
var
|
|
6861
|
+
var generateId3;
|
|
6833
6862
|
var readFileAsText2;
|
|
6834
|
-
var
|
|
6863
|
+
var renderApps2;
|
|
6835
6864
|
var getMainApps2;
|
|
6865
|
+
var showPublishModal2;
|
|
6836
6866
|
function initAppsIo(deps) {
|
|
6837
|
-
({ generateId:
|
|
6838
|
-
}
|
|
6839
|
-
async function addAppFromZip(name, arrayBuffer, icon, tags, openMode) {
|
|
6840
|
-
var files = await extractZip(arrayBuffer);
|
|
6841
|
-
var bundledHtml = await bundleZip(files);
|
|
6842
|
-
var encoded = btoa(unescape(encodeURIComponent(bundledHtml)));
|
|
6843
|
-
var app = {
|
|
6844
|
-
id: generateId4(),
|
|
6845
|
-
name,
|
|
6846
|
-
description: "",
|
|
6847
|
-
source: "zip",
|
|
6848
|
-
url: null,
|
|
6849
|
-
blob: encoded,
|
|
6850
|
-
tags,
|
|
6851
|
-
openMode,
|
|
6852
|
-
icon: icon || "📦",
|
|
6853
|
-
screenshot: null,
|
|
6854
|
-
favorite: false,
|
|
6855
|
-
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6856
|
-
lastOpenedAt: null
|
|
6857
|
-
};
|
|
6858
|
-
await saveApp(app);
|
|
6859
|
-
return app;
|
|
6860
|
-
}
|
|
6861
|
-
function addAppFromUrl(name, url, icon, tags, openMode) {
|
|
6862
|
-
var app = {
|
|
6863
|
-
id: generateId4(),
|
|
6864
|
-
name,
|
|
6865
|
-
description: "",
|
|
6866
|
-
source: "url",
|
|
6867
|
-
url,
|
|
6868
|
-
blob: null,
|
|
6869
|
-
tags,
|
|
6870
|
-
openMode,
|
|
6871
|
-
icon: icon || "📝",
|
|
6872
|
-
screenshot: null,
|
|
6873
|
-
favorite: false,
|
|
6874
|
-
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6875
|
-
lastOpenedAt: null
|
|
6876
|
-
};
|
|
6877
|
-
return saveApp(app).then(function() {
|
|
6878
|
-
return app;
|
|
6879
|
-
});
|
|
6880
|
-
}
|
|
6881
|
-
function addAppFromFile(name, file, icon, tags, openMode) {
|
|
6882
|
-
return readFileAsText2(file).then(function(content) {
|
|
6883
|
-
var encoded = btoa(unescape(encodeURIComponent(content)));
|
|
6884
|
-
var app = {
|
|
6885
|
-
id: generateId4(),
|
|
6886
|
-
name,
|
|
6887
|
-
description: "",
|
|
6888
|
-
source: "local",
|
|
6889
|
-
url: null,
|
|
6890
|
-
blob: encoded,
|
|
6891
|
-
tags,
|
|
6892
|
-
openMode,
|
|
6893
|
-
icon: icon || "📝",
|
|
6894
|
-
screenshot: null,
|
|
6895
|
-
favorite: false,
|
|
6896
|
-
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6897
|
-
lastOpenedAt: null
|
|
6898
|
-
};
|
|
6899
|
-
return saveApp(app).then(function() {
|
|
6900
|
-
return app;
|
|
6901
|
-
});
|
|
6902
|
-
});
|
|
6867
|
+
({ generateId: generateId3, readFileAsText: readFileAsText2, renderApps: renderApps2, getMainApps: getMainApps2, showPublishModal: showPublishModal2 } = deps);
|
|
6903
6868
|
}
|
|
6904
|
-
function
|
|
6905
|
-
var encoded = btoa(unescape(encodeURIComponent(
|
|
6869
|
+
function createAppFromHtml(name, html, icon, tags, description) {
|
|
6870
|
+
var encoded = btoa(unescape(encodeURIComponent(html)));
|
|
6906
6871
|
var app = {
|
|
6907
|
-
id:
|
|
6872
|
+
id: generateId3(),
|
|
6908
6873
|
name,
|
|
6909
|
-
description:
|
|
6910
|
-
source: "
|
|
6874
|
+
description: description || "",
|
|
6875
|
+
source: "create",
|
|
6911
6876
|
url: null,
|
|
6912
6877
|
blob: encoded,
|
|
6913
|
-
tags,
|
|
6914
|
-
openMode,
|
|
6878
|
+
tags: tags || [],
|
|
6915
6879
|
icon: icon || "📝",
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6919
|
-
lastOpenedAt: null
|
|
6880
|
+
published: false,
|
|
6881
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6920
6882
|
};
|
|
6921
6883
|
return saveApp(app).then(function() {
|
|
6884
|
+
try {
|
|
6885
|
+
getMainApps2().push(app);
|
|
6886
|
+
} catch (e) {
|
|
6887
|
+
}
|
|
6888
|
+
if (typeof showPublishModal2 === "function") showPublishModal2(app.id, { unlisted: true });
|
|
6922
6889
|
return app;
|
|
6923
6890
|
});
|
|
6924
6891
|
}
|
|
@@ -6927,7 +6894,7 @@
|
|
|
6927
6894
|
function showModal() {
|
|
6928
6895
|
document.getElementById("modal-overlay").hidden = false;
|
|
6929
6896
|
document.getElementById("modal-title").textContent = t("addModal.title");
|
|
6930
|
-
switchTab("
|
|
6897
|
+
switchTab("paste");
|
|
6931
6898
|
}
|
|
6932
6899
|
function requireSignInThen(next) {
|
|
6933
6900
|
if (getCortexOwnerToken()) {
|
|
@@ -6975,7 +6942,6 @@
|
|
|
6975
6942
|
}
|
|
6976
6943
|
function closeModal() {
|
|
6977
6944
|
document.getElementById("modal-overlay").hidden = true;
|
|
6978
|
-
document.getElementById("app-url").value = "";
|
|
6979
6945
|
document.getElementById("app-name").value = "";
|
|
6980
6946
|
document.getElementById("app-icon").value = "";
|
|
6981
6947
|
document.getElementById("app-tags").value = "";
|
|
@@ -7029,7 +6995,6 @@
|
|
|
7029
6995
|
var name = document.getElementById("app-name").value.trim();
|
|
7030
6996
|
var icon = document.getElementById("app-icon").value.trim();
|
|
7031
6997
|
var tagsRaw = document.getElementById("app-tags").value.trim();
|
|
7032
|
-
var openMode = "tab";
|
|
7033
6998
|
var tags = tagsRaw ? tagsRaw.split(",").map(function(t2) {
|
|
7034
6999
|
return t2.trim();
|
|
7035
7000
|
}).filter(Boolean) : [];
|
|
@@ -7052,76 +7017,110 @@
|
|
|
7052
7017
|
app.name = name;
|
|
7053
7018
|
app.icon = icon || app.icon;
|
|
7054
7019
|
app.tags = tags;
|
|
7055
|
-
app.openMode = openMode;
|
|
7056
7020
|
saveApp(app).then(function() {
|
|
7057
7021
|
closeModal();
|
|
7058
|
-
|
|
7022
|
+
renderApps2();
|
|
7059
7023
|
});
|
|
7060
7024
|
return;
|
|
7061
7025
|
}
|
|
7062
7026
|
var activeTab = document.querySelector(".modal-tab.active");
|
|
7063
|
-
var tabName = activeTab ? activeTab.getAttribute("data-tab") : "
|
|
7064
|
-
if (tabName === "
|
|
7065
|
-
var url = document.getElementById("app-url").value.trim();
|
|
7066
|
-
if (!url) {
|
|
7067
|
-
showNotice("Please enter a URL");
|
|
7068
|
-
return;
|
|
7069
|
-
}
|
|
7070
|
-
if (!name) {
|
|
7071
|
-
try {
|
|
7072
|
-
name = new URL(url).hostname;
|
|
7073
|
-
} catch (e) {
|
|
7074
|
-
name = url;
|
|
7075
|
-
}
|
|
7076
|
-
}
|
|
7077
|
-
addAppFromUrl(name, url, icon, tags, openMode).then(function() {
|
|
7078
|
-
closeModal();
|
|
7079
|
-
renderApps3();
|
|
7080
|
-
});
|
|
7081
|
-
} else if (tabName === "paste") {
|
|
7027
|
+
var tabName = activeTab ? activeTab.getAttribute("data-tab") : "paste";
|
|
7028
|
+
if (tabName === "paste") {
|
|
7082
7029
|
var pastedCode = document.getElementById("app-paste-code").value.trim();
|
|
7083
7030
|
if (!pastedCode) {
|
|
7084
7031
|
showNotice("Please paste your HTML source code");
|
|
7085
7032
|
return;
|
|
7086
7033
|
}
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
addAppFromSource(name, pastedCode, icon, tags, openMode).then(function() {
|
|
7092
|
-
closeModal();
|
|
7093
|
-
renderApps3();
|
|
7094
|
-
});
|
|
7034
|
+
var meta = parseAppMeta(pastedCode);
|
|
7035
|
+
if (!name) name = meta.name || "Pasted App";
|
|
7036
|
+
closeModal();
|
|
7037
|
+
createAppFromHtml(name, pastedCode, icon, tags, meta.description);
|
|
7095
7038
|
} else if (tabName === "file") {
|
|
7096
7039
|
if (!selectedFile) {
|
|
7097
7040
|
showNotice("Please select a file");
|
|
7098
7041
|
return;
|
|
7099
7042
|
}
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
|
|
7104
|
-
|
|
7105
|
-
|
|
7106
|
-
|
|
7043
|
+
var file = selectedFile;
|
|
7044
|
+
if (file.name.toLowerCase().endsWith(".zip")) {
|
|
7045
|
+
if (!name) name = file.name.replace(/\.zip$/i, "");
|
|
7046
|
+
file.arrayBuffer().then(function(arrayBuffer) {
|
|
7047
|
+
return extractZip(arrayBuffer);
|
|
7048
|
+
}).then(function(files) {
|
|
7049
|
+
return bundleZip(files);
|
|
7050
|
+
}).then(function(html) {
|
|
7107
7051
|
closeModal();
|
|
7108
|
-
|
|
7052
|
+
return createAppFromHtml(name, html, icon, tags, parseAppMeta(html).description);
|
|
7109
7053
|
}).catch(function(err) {
|
|
7110
7054
|
showNotice("ZIP import failed: " + (err.message || err));
|
|
7111
7055
|
});
|
|
7112
7056
|
} else {
|
|
7113
|
-
if (!name)
|
|
7114
|
-
|
|
7115
|
-
}
|
|
7116
|
-
addAppFromFile(name, selectedFile, icon, tags, openMode).then(function() {
|
|
7057
|
+
if (!name) name = file.name.replace(/\.html?$/i, "");
|
|
7058
|
+
readFileAsText2(file).then(function(html) {
|
|
7117
7059
|
closeModal();
|
|
7118
|
-
|
|
7060
|
+
createAppFromHtml(name, html, icon, tags, parseAppMeta(html).description);
|
|
7119
7061
|
});
|
|
7120
7062
|
}
|
|
7121
7063
|
}
|
|
7122
7064
|
}
|
|
7123
|
-
|
|
7124
|
-
|
|
7065
|
+
|
|
7066
|
+
// src/static/app-catalog/js/favorites.js
|
|
7067
|
+
var KEY2 = "app-catalog.favorites";
|
|
7068
|
+
var favSet = /* @__PURE__ */ new Set();
|
|
7069
|
+
function base2() {
|
|
7070
|
+
return (loadConfig().aimeatUrl || "").replace(/\/+$/, "");
|
|
7071
|
+
}
|
|
7072
|
+
function isFavorite(ref) {
|
|
7073
|
+
return favSet.has(ref);
|
|
7074
|
+
}
|
|
7075
|
+
function loadFavorites() {
|
|
7076
|
+
var token = getCortexOwnerToken();
|
|
7077
|
+
var b = base2();
|
|
7078
|
+
if (!token || !b) {
|
|
7079
|
+
favSet = /* @__PURE__ */ new Set();
|
|
7080
|
+
return Promise.resolve();
|
|
7081
|
+
}
|
|
7082
|
+
return fetch(b + "/v1/memory/" + encodeURIComponent(KEY2), { headers: { "Authorization": "Bearer " + token } }).then(function(r) {
|
|
7083
|
+
return r.ok ? r.json() : null;
|
|
7084
|
+
}).then(function(j) {
|
|
7085
|
+
var refs = j && j.data && j.data.value && Array.isArray(j.data.value.refs) ? j.data.value.refs : [];
|
|
7086
|
+
favSet = new Set(refs.filter(function(x) {
|
|
7087
|
+
return typeof x === "string";
|
|
7088
|
+
}));
|
|
7089
|
+
}).catch(function() {
|
|
7090
|
+
});
|
|
7091
|
+
}
|
|
7092
|
+
function persist2() {
|
|
7093
|
+
var token = getCortexOwnerToken();
|
|
7094
|
+
var b = base2();
|
|
7095
|
+
if (!token || !b) return Promise.resolve();
|
|
7096
|
+
return fetch(b + "/v1/memory", {
|
|
7097
|
+
method: "POST",
|
|
7098
|
+
headers: { "Content-Type": "application/json", "Authorization": "Bearer " + token },
|
|
7099
|
+
body: JSON.stringify({
|
|
7100
|
+
key: KEY2,
|
|
7101
|
+
value: { version: 1, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), refs: Array.from(favSet) },
|
|
7102
|
+
visibility: "private"
|
|
7103
|
+
})
|
|
7104
|
+
}).catch(function() {
|
|
7105
|
+
});
|
|
7106
|
+
}
|
|
7107
|
+
function toggleFavorite(ref) {
|
|
7108
|
+
var now;
|
|
7109
|
+
if (favSet.has(ref)) {
|
|
7110
|
+
favSet.delete(ref);
|
|
7111
|
+
now = false;
|
|
7112
|
+
} else {
|
|
7113
|
+
favSet.add(ref);
|
|
7114
|
+
now = true;
|
|
7115
|
+
}
|
|
7116
|
+
return persist2().then(function() {
|
|
7117
|
+
return now;
|
|
7118
|
+
});
|
|
7119
|
+
}
|
|
7120
|
+
function favStarHtml(ref) {
|
|
7121
|
+
var on = favSet.has(ref);
|
|
7122
|
+
var title = on ? t("fav.remove") || "Remove from favourites" : t("fav.add") || "Add to favourites";
|
|
7123
|
+
return '<button class="fav-toggle' + (on ? " on" : "") + `" onclick="event.stopPropagation(); window._launcher.toggleFavorite('` + String(ref).replace(/'/g, "\\'") + `')" title="` + title + '">' + (on ? "⭐" : "☆") + "</button>";
|
|
7125
7124
|
}
|
|
7126
7125
|
|
|
7127
7126
|
// src/static/app-catalog/js/server-io.js
|
|
@@ -7133,137 +7132,18 @@
|
|
|
7133
7132
|
var setOwnServerApps;
|
|
7134
7133
|
var getActiveTag;
|
|
7135
7134
|
var getSearchQuery;
|
|
7136
|
-
var
|
|
7137
|
-
var
|
|
7135
|
+
var generateId4;
|
|
7136
|
+
var renderApps3;
|
|
7138
7137
|
var refreshAll2;
|
|
7139
7138
|
function initServerIo(deps) {
|
|
7140
|
-
({ getMainApps: getMainApps3, getServerState: getServerState2, getServerManifests: getServerManifests3, setServerManifests, getOwnServerApps, setOwnServerApps, getActiveTag, getSearchQuery, generateId:
|
|
7141
|
-
}
|
|
7142
|
-
var aimeatAppsCache = [];
|
|
7143
|
-
function formatFileSize(bytes) {
|
|
7144
|
-
if (bytes < 1024) return bytes + " B";
|
|
7145
|
-
if (bytes < 1048576) return (bytes / 1024).toFixed(1) + " KB";
|
|
7146
|
-
return (bytes / 1048576).toFixed(1) + " MB";
|
|
7147
|
-
}
|
|
7148
|
-
function importFromAimeat() {
|
|
7149
|
-
var config = loadConfig();
|
|
7150
|
-
if (!config.aimeatUrl) {
|
|
7151
|
-
showNotice("Set AIMEAT server URL in Settings first");
|
|
7152
|
-
return;
|
|
7153
|
-
}
|
|
7154
|
-
var aimeatUrl = config.aimeatUrl.replace(/\/+$/, "");
|
|
7155
|
-
closeModal();
|
|
7156
|
-
fetch(aimeatUrl + "/v1/apps?include_peers=true").then(function(resp) {
|
|
7157
|
-
if (!resp.ok) throw new Error("Server returned " + resp.status);
|
|
7158
|
-
return resp.json();
|
|
7159
|
-
}).then(function(json) {
|
|
7160
|
-
var apps = json.data && json.data.apps ? json.data.apps : [];
|
|
7161
|
-
var peerApps = json.data && json.data.peer_apps ? json.data.peer_apps : [];
|
|
7162
|
-
for (var p = 0; p < peerApps.length; p++) {
|
|
7163
|
-
peerApps[p]._from_peer = true;
|
|
7164
|
-
}
|
|
7165
|
-
var allFetched = apps.concat(peerApps);
|
|
7166
|
-
if (allFetched.length === 0) {
|
|
7167
|
-
showNotice("No apps found on the AIMEAT server");
|
|
7168
|
-
return;
|
|
7169
|
-
}
|
|
7170
|
-
aimeatAppsCache = allFetched;
|
|
7171
|
-
showAimeatImportDialog(allFetched, aimeatUrl);
|
|
7172
|
-
}).catch(function(err) {
|
|
7173
|
-
var msg = "Failed to fetch apps from AIMEAT server.\n\n" + (err.message || err);
|
|
7174
|
-
if (err.message && err.message.indexOf("Failed to fetch") !== -1) {
|
|
7175
|
-
msg += "\n\nIf the launcher is opened via file://, CORS will block the request. Open it from the AIMEAT server instead.";
|
|
7176
|
-
}
|
|
7177
|
-
showNotice(msg);
|
|
7178
|
-
});
|
|
7179
|
-
}
|
|
7180
|
-
function showAimeatImportDialog(apps, aimeatUrl) {
|
|
7181
|
-
var listEl = document.getElementById("aimeat-app-list");
|
|
7182
|
-
var html = "";
|
|
7183
|
-
for (var i = 0; i < apps.length; i++) {
|
|
7184
|
-
var app = apps[i];
|
|
7185
|
-
var displayName = app.manifest && app.manifest.name ? app.manifest.name : app.filename;
|
|
7186
|
-
var displayAuthor = app.manifest && app.manifest.authorDisplay ? app.manifest.authorDisplay : app.owner || "";
|
|
7187
|
-
var displayDesc = app.manifest && app.manifest.description ? app.manifest.description : "";
|
|
7188
|
-
var displayVer = app.version_number ? "v" + app.version_number : "";
|
|
7189
|
-
var displayCat = app.manifest && app.manifest.category ? app.manifest.category : "";
|
|
7190
|
-
var peerLabel = app._from_peer && app._peer_node ? " · 🌐 " + escapeHtml(app._peer_node) : "";
|
|
7191
|
-
html += '<div class="aimeat-app-item"><input type="checkbox" data-index="' + i + '" checked/><div class="aimeat-app-info"><div class="aimeat-app-name">' + escapeHtml(displayName) + (displayVer ? ' <span style="opacity:.5;font-size:.85em">' + escapeHtml(displayVer) + "</span>" : "") + '</div><div class="aimeat-app-size">' + formatFileSize(app.size) + (displayAuthor ? " · " + escapeHtml(displayAuthor) : "") + (displayCat ? " · " + escapeHtml(displayCat) : "") + peerLabel + "</div>" + (displayDesc ? '<div class="aimeat-app-size" style="opacity:.6">' + escapeHtml(displayDesc.substring(0, 100)) + "</div>" : "") + '</div><select data-index="' + i + '"><option value="link">Link (online only)</option><option value="download">Download (offline)</option></select></div>';
|
|
7192
|
-
}
|
|
7193
|
-
listEl.innerHTML = html;
|
|
7194
|
-
listEl.dataset.aimeatUrl = aimeatUrl;
|
|
7195
|
-
document.getElementById("aimeat-import-overlay").hidden = false;
|
|
7196
|
-
}
|
|
7197
|
-
function processAimeatImport() {
|
|
7198
|
-
var listEl = document.getElementById("aimeat-app-list");
|
|
7199
|
-
var aimeatUrl = listEl.dataset.aimeatUrl;
|
|
7200
|
-
var checkboxes = listEl.querySelectorAll('input[type="checkbox"]');
|
|
7201
|
-
var selects = listEl.querySelectorAll("select");
|
|
7202
|
-
var config = loadConfig();
|
|
7203
|
-
var defaultOpenMode = config.defaultOpenMode || "tab";
|
|
7204
|
-
var toImport = [];
|
|
7205
|
-
for (var i = 0; i < checkboxes.length; i++) {
|
|
7206
|
-
if (checkboxes[i].checked) {
|
|
7207
|
-
var idx = parseInt(checkboxes[i].getAttribute("data-index"), 10);
|
|
7208
|
-
var mode = selects[i].value;
|
|
7209
|
-
toImport.push({ app: aimeatAppsCache[idx], mode });
|
|
7210
|
-
}
|
|
7211
|
-
}
|
|
7212
|
-
if (toImport.length === 0) {
|
|
7213
|
-
showNotice("No apps selected");
|
|
7214
|
-
return;
|
|
7215
|
-
}
|
|
7216
|
-
var promises = [];
|
|
7217
|
-
for (var j = 0; j < toImport.length; j++) {
|
|
7218
|
-
(function(item) {
|
|
7219
|
-
var app = item.app;
|
|
7220
|
-
var name = app.manifest && app.manifest.name ? app.manifest.name : app.filename.replace(/\.html?$/i, "");
|
|
7221
|
-
var importedVersion = app.version_number || 1;
|
|
7222
|
-
var baseUrl = app._from_peer && app._peer_url ? app._peer_url.replace(/\/+$/, "") : aimeatUrl;
|
|
7223
|
-
if (item.mode === "link") {
|
|
7224
|
-
var inlineUrl = baseUrl + app.download_url + "?mode=inline";
|
|
7225
|
-
promises.push(addAppFromUrl(name, inlineUrl, "📦", ["aimeat"], defaultOpenMode));
|
|
7226
|
-
} else {
|
|
7227
|
-
var downloadUrl = baseUrl + app.download_url;
|
|
7228
|
-
promises.push(
|
|
7229
|
-
fetch(downloadUrl).then(function(resp) {
|
|
7230
|
-
if (!resp.ok) throw new Error("Download failed: " + resp.status);
|
|
7231
|
-
return resp.text();
|
|
7232
|
-
}).then(function(content) {
|
|
7233
|
-
var encoded = btoa(unescape(encodeURIComponent(content)));
|
|
7234
|
-
var record = {
|
|
7235
|
-
id: generateId5(),
|
|
7236
|
-
name,
|
|
7237
|
-
description: app.manifest && app.manifest.description ? app.manifest.description : "",
|
|
7238
|
-
source: "aimeat",
|
|
7239
|
-
aimeatOwner: app.owner || null,
|
|
7240
|
-
aimeatFilename: app.filename || null,
|
|
7241
|
-
aimeatVersion: importedVersion,
|
|
7242
|
-
url: null,
|
|
7243
|
-
blob: encoded,
|
|
7244
|
-
tags: ["aimeat"],
|
|
7245
|
-
openMode: defaultOpenMode,
|
|
7246
|
-
icon: "📦",
|
|
7247
|
-
screenshot: null,
|
|
7248
|
-
favorite: false,
|
|
7249
|
-
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7250
|
-
lastOpenedAt: null
|
|
7251
|
-
};
|
|
7252
|
-
return saveApp(record);
|
|
7253
|
-
})
|
|
7254
|
-
);
|
|
7255
|
-
}
|
|
7256
|
-
})(toImport[j]);
|
|
7257
|
-
}
|
|
7258
|
-
Promise.all(promises).then(function() {
|
|
7259
|
-
document.getElementById("aimeat-import-overlay").hidden = true;
|
|
7260
|
-
renderApps4();
|
|
7261
|
-
}).catch(function(err) {
|
|
7262
|
-
showNotice("Import error: " + (err.message || err));
|
|
7263
|
-
});
|
|
7139
|
+
({ getMainApps: getMainApps3, getServerState: getServerState2, getServerManifests: getServerManifests3, setServerManifests, getOwnServerApps, setOwnServerApps, getActiveTag, getSearchQuery, generateId: generateId4, renderApps: renderApps3, refreshAll: refreshAll2 } = deps);
|
|
7264
7140
|
}
|
|
7141
|
+
var lastAllServerApps = [];
|
|
7142
|
+
var lastAimeatUrl = "";
|
|
7265
7143
|
var publishAppId = null;
|
|
7266
|
-
|
|
7144
|
+
var publishUnlisted = false;
|
|
7145
|
+
function showPublishModal3(appId, opts) {
|
|
7146
|
+
publishUnlisted = !!(opts && opts.unlisted);
|
|
7267
7147
|
var app = null;
|
|
7268
7148
|
for (var i = 0; i < getMainApps3().length; i++) {
|
|
7269
7149
|
if (getMainApps3()[i].id === appId) {
|
|
@@ -7385,7 +7265,16 @@
|
|
|
7385
7265
|
app.publishedVersionNumber = json.data.version_number || 1;
|
|
7386
7266
|
app.publishedVersionsUrl = json.data.versions_url || null;
|
|
7387
7267
|
saveApp(app).then(function() {
|
|
7388
|
-
|
|
7268
|
+
if (publishUnlisted) {
|
|
7269
|
+
app.parked = true;
|
|
7270
|
+
statusEl.textContent = "✔ " + (t("publish.savedUnlisted") || "Saved (unlisted)");
|
|
7271
|
+
try {
|
|
7272
|
+
toggleParkApp(filename, true);
|
|
7273
|
+
} catch (e) {
|
|
7274
|
+
}
|
|
7275
|
+
}
|
|
7276
|
+
publishUnlisted = false;
|
|
7277
|
+
loadPublishedApps2();
|
|
7389
7278
|
setTimeout(function() {
|
|
7390
7279
|
var ov = document.getElementById("publish-overlay");
|
|
7391
7280
|
if (ov) ov.hidden = true;
|
|
@@ -7539,7 +7428,7 @@
|
|
|
7539
7428
|
statusEl.textContent = "✔ " + t("subModal.assigned") + " — " + sub + "." + apexHostLabel();
|
|
7540
7429
|
return loadSubdomainSites();
|
|
7541
7430
|
}).then(function() {
|
|
7542
|
-
|
|
7431
|
+
loadPublishedApps2();
|
|
7543
7432
|
}).catch(function(err) {
|
|
7544
7433
|
statusEl.style.color = "#ef4444";
|
|
7545
7434
|
statusEl.textContent = err.message || String(err);
|
|
@@ -7557,7 +7446,7 @@
|
|
|
7557
7446
|
subdomainModalState.existingSub = null;
|
|
7558
7447
|
return loadSubdomainSites();
|
|
7559
7448
|
}).then(function() {
|
|
7560
|
-
|
|
7449
|
+
loadPublishedApps2();
|
|
7561
7450
|
}).catch(function(err) {
|
|
7562
7451
|
statusEl.style.color = "#ef4444";
|
|
7563
7452
|
statusEl.textContent = err.message || String(err);
|
|
@@ -7882,7 +7771,7 @@
|
|
|
7882
7771
|
}
|
|
7883
7772
|
return page(0);
|
|
7884
7773
|
}
|
|
7885
|
-
function
|
|
7774
|
+
function loadPublishedApps2() {
|
|
7886
7775
|
var config = loadConfig();
|
|
7887
7776
|
var aimeatUrl = config.aimeatUrl ? config.aimeatUrl.replace(/\/+$/, "") : "";
|
|
7888
7777
|
var communitySection = document.getElementById("community-section");
|
|
@@ -7901,10 +7790,10 @@
|
|
|
7901
7790
|
}
|
|
7902
7791
|
} catch (e) {
|
|
7903
7792
|
}
|
|
7904
|
-
getAllApps().then(function() {
|
|
7793
|
+
Promise.all([getAllApps(), loadFavorites(), loadPromoted()]).then(function() {
|
|
7905
7794
|
if (!aimeatUrl) {
|
|
7906
7795
|
setOwnServerApps([]);
|
|
7907
|
-
|
|
7796
|
+
renderApps3();
|
|
7908
7797
|
if (communitySection) communitySection.style.display = "none";
|
|
7909
7798
|
return;
|
|
7910
7799
|
}
|
|
@@ -7924,15 +7813,18 @@
|
|
|
7924
7813
|
var communityApps = currentOwner ? serverApps.filter(function(a) {
|
|
7925
7814
|
return !sameOwner(a.owner, currentOwner);
|
|
7926
7815
|
}) : serverApps;
|
|
7816
|
+
lastAllServerApps = serverApps;
|
|
7817
|
+
lastAimeatUrl = aimeatUrl;
|
|
7927
7818
|
return loadSubdomainSites().then(function() {
|
|
7928
7819
|
setOwnServerApps(currentOwner ? ownApps : []);
|
|
7929
|
-
|
|
7820
|
+
renderApps3();
|
|
7930
7821
|
renderCommunityApps(communityApps, aimeatUrl, communitySection, communityGrid, communityCountEl, currentOwner);
|
|
7822
|
+
renderFavorites(serverApps, aimeatUrl);
|
|
7931
7823
|
applyServerFilter();
|
|
7932
7824
|
});
|
|
7933
7825
|
}).catch(function() {
|
|
7934
7826
|
setOwnServerApps([]);
|
|
7935
|
-
|
|
7827
|
+
renderApps3();
|
|
7936
7828
|
if (communitySection) communitySection.style.display = "none";
|
|
7937
7829
|
});
|
|
7938
7830
|
});
|
|
@@ -7962,6 +7854,21 @@
|
|
|
7962
7854
|
var sectionEl = document.getElementById("community-section");
|
|
7963
7855
|
if (sectionEl) sectionEl.style.display = filtering && shown === 0 ? "none" : "";
|
|
7964
7856
|
}
|
|
7857
|
+
function publishedCardHtml(sa, aimeatUrl) {
|
|
7858
|
+
var owner = sa.owner || "";
|
|
7859
|
+
var fn = sa.filename || "";
|
|
7860
|
+
var ref = owner + "/" + fn;
|
|
7861
|
+
var m = sa.manifest || {};
|
|
7862
|
+
var name = m.name || fn;
|
|
7863
|
+
var version = sa.version_number ? "v" + sa.version_number : "";
|
|
7864
|
+
var description = m.descriptions && m.descriptions[getLang()] || m.description || "";
|
|
7865
|
+
var date = sa.created_at ? new Date(sa.created_at).toLocaleDateString() : "";
|
|
7866
|
+
var author = m.authorDisplay || owner;
|
|
7867
|
+
var viewUrl = aimeatUrl + "/v1/apps/" + encodeURIComponent(owner) + "/" + encodeURIComponent(fn);
|
|
7868
|
+
var shipsAgent = !!(m.cortex && m.cortex.agents && m.cortex.agents.length);
|
|
7869
|
+
return '<div class="published-card"' + filterAttr(name, m.tags || []) + ">" + favStarHtml(ref) + '<div class="published-card-name">' + escapeHtml(name) + "</div>" + (description ? '<div class="published-card-desc">' + escapeHtml(description) + "</div>" : "") + '<div class="published-card-footer"><div class="published-card-metaline"><span class="pcm-main" style="color:var(--accent)">👤 ' + escapeHtml(author) + "</span>" + (date ? '<span class="pcm-date">' + date + "</span>" : "") + `</div><div class="published-card-actions"><button onclick="window._launcher.viewPublished('` + escapeHtml(viewUrl) + "?mode=inline', '" + jsArg(name) + `')">` + t("card.view") + "</button>" + // Fork is offered on a community app only when its owner marked it forkable.
|
|
7870
|
+
(sa.forkable ? `<button onclick="window._launcher.forkVersion('` + escapeHtml(owner) + "', '" + escapeHtml(fn) + "', " + (sa.version_number || 0) + ')" title="' + escapeHtml(t("card.forkHint")) + '">' + t("card.fork") + "</button>" : "") + (shipsAgent ? `<button onclick="window._launcher.showAppAgentsModal('` + jsArg(owner) + "', '" + jsArg(fn) + `')" title="` + escapeHtml(t("card.agentHint")) + '">' + t("card.agent") + "</button>" : "") + "</div>" + (version || sa.forks && sa.forks > 0 || shipsAgent ? '<div class="published-card-badgerow">' + (shipsAgent ? '<span class="pcb-agent" title="' + escapeHtml(t("card.agentHint")) + '">🤖</span>' : "") + (sa.forks && sa.forks > 0 ? '<span class="pcb-forks" title="' + escapeHtml(t("card.forksHint")) + `" onclick="window._launcher.showLineageModal('` + escapeHtml(owner) + "', '" + escapeHtml(fn) + `')">⑂ ` + sa.forks + "</span>" : "") + (version ? '<span class="pcb-version">' + escapeHtml(version) + "</span>" : "") + "</div>" : "") + "</div></div>";
|
|
7871
|
+
}
|
|
7965
7872
|
function renderCommunityApps(serverApps, aimeatUrl, section, grid, countEl, currentOwner) {
|
|
7966
7873
|
if (!section || !grid || !countEl) return;
|
|
7967
7874
|
if (serverApps.length === 0) {
|
|
@@ -7973,22 +7880,51 @@
|
|
|
7973
7880
|
section.style.display = "";
|
|
7974
7881
|
countEl.textContent = "(" + serverApps.length + ")";
|
|
7975
7882
|
var html = "";
|
|
7976
|
-
for (var i = 0; i < serverApps.length; i++)
|
|
7977
|
-
var sa = serverApps[i];
|
|
7978
|
-
var name = sa.manifest && sa.manifest.name ? sa.manifest.name : sa.filename || "";
|
|
7979
|
-
var version = sa.version_number ? "v" + sa.version_number : "";
|
|
7980
|
-
var description = sa.manifest && sa.manifest.description ? sa.manifest.description : "";
|
|
7981
|
-
var date = sa.created_at ? new Date(sa.created_at).toLocaleDateString() : "";
|
|
7982
|
-
var author = sa.manifest && sa.manifest.authorDisplay ? sa.manifest.authorDisplay : sa.owner || "";
|
|
7983
|
-
var viewUrl = aimeatUrl + "/v1/apps/" + encodeURIComponent(sa.owner || "") + "/" + encodeURIComponent(sa.filename || "");
|
|
7984
|
-
var shipsAgent = !!(sa.manifest && sa.manifest.cortex && sa.manifest.cortex.agents && sa.manifest.cortex.agents.length);
|
|
7985
|
-
html += '<div class="published-card"' + filterAttr(name, sa.manifest && sa.manifest.tags || []) + '><div class="published-card-name">' + escapeHtml(name) + "</div>" + (description ? '<div class="published-card-desc">' + escapeHtml(description) + "</div>" : "") + '<div class="published-card-footer"><div class="published-card-metaline"><span class="pcm-main" style="color:var(--accent)">👤 ' + escapeHtml(author) + "</span>" + (date ? '<span class="pcm-date">' + date + "</span>" : "") + `</div><div class="published-card-actions"><button onclick="window._launcher.viewPublished('` + escapeHtml(viewUrl) + "?mode=inline', '" + jsArg(name) + `')">` + t("card.view") + "</button>" + // Fork is offered on a community (someone else's) app only when its owner
|
|
7986
|
-
// marked it forkable; otherwise the server would reject the fork (403).
|
|
7987
|
-
(sa.forkable ? `<button onclick="window._launcher.forkVersion('` + escapeHtml(sa.owner || "") + "', '" + escapeHtml(sa.filename || "") + "', " + (sa.version_number || 0) + ')" title="' + escapeHtml(t("card.forkHint")) + '">' + t("card.fork") + "</button>" : "") + (shipsAgent ? `<button onclick="window._launcher.showAppAgentsModal('` + jsArg(sa.owner || "") + "', '" + jsArg(sa.filename || "") + `')" title="` + escapeHtml(t("card.agentHint")) + '">' + t("card.agent") + "</button>" : "") + "</div>" + (version || sa.forks && sa.forks > 0 || shipsAgent ? '<div class="published-card-badgerow">' + (shipsAgent ? '<span class="pcb-agent" title="' + escapeHtml(t("card.agentHint")) + '">🤖</span>' : "") + (sa.forks && sa.forks > 0 ? '<span class="pcb-forks" title="' + escapeHtml(t("card.forksHint")) + `" onclick="window._launcher.showLineageModal('` + escapeHtml(sa.owner || "") + "', '" + escapeHtml(sa.filename || "") + `')">⑂ ` + sa.forks + "</span>" : "") + (version ? '<span class="pcb-version">' + escapeHtml(version) + "</span>" : "") + "</div>" : "") + "</div></div>";
|
|
7988
|
-
}
|
|
7883
|
+
for (var i = 0; i < serverApps.length; i++) html += publishedCardHtml(serverApps[i], aimeatUrl);
|
|
7989
7884
|
grid.innerHTML = html;
|
|
7990
7885
|
updateCommunityEmpty();
|
|
7991
7886
|
}
|
|
7887
|
+
function renderFavorites(allServerApps, aimeatUrl) {
|
|
7888
|
+
var section = document.getElementById("favorites-section");
|
|
7889
|
+
var grid = document.getElementById("favorites-grid");
|
|
7890
|
+
var countEl = document.getElementById("favorites-count");
|
|
7891
|
+
if (!section || !grid) return;
|
|
7892
|
+
var favs = (allServerApps || []).filter(function(sa) {
|
|
7893
|
+
return isFavorite((sa.owner || "") + "/" + (sa.filename || ""));
|
|
7894
|
+
});
|
|
7895
|
+
if (favs.length === 0) {
|
|
7896
|
+
section.style.display = "none";
|
|
7897
|
+
grid.innerHTML = "";
|
|
7898
|
+
return;
|
|
7899
|
+
}
|
|
7900
|
+
section.style.display = "";
|
|
7901
|
+
if (countEl) countEl.textContent = "(" + favs.length + ")";
|
|
7902
|
+
var html = "";
|
|
7903
|
+
for (var i = 0; i < favs.length; i++) html += publishedCardHtml(favs[i], aimeatUrl);
|
|
7904
|
+
grid.innerHTML = html;
|
|
7905
|
+
}
|
|
7906
|
+
function refreshFavoritesUI() {
|
|
7907
|
+
renderFavorites(lastAllServerApps, lastAimeatUrl);
|
|
7908
|
+
var currentOwner = null;
|
|
7909
|
+
try {
|
|
7910
|
+
var s = window.AIMEAT && window.AIMEAT.auth && window.AIMEAT.auth.getSession();
|
|
7911
|
+
currentOwner = s && s.owner || JSON.parse(localStorage.getItem("aimeat_session") || "{}").owner || null;
|
|
7912
|
+
} catch (e) {
|
|
7913
|
+
}
|
|
7914
|
+
var communityApps = currentOwner ? lastAllServerApps.filter(function(a) {
|
|
7915
|
+
return !sameOwner(a.owner, currentOwner);
|
|
7916
|
+
}) : lastAllServerApps;
|
|
7917
|
+
renderCommunityApps(
|
|
7918
|
+
communityApps,
|
|
7919
|
+
lastAimeatUrl,
|
|
7920
|
+
document.getElementById("community-section"),
|
|
7921
|
+
document.getElementById("community-grid"),
|
|
7922
|
+
document.getElementById("community-count"),
|
|
7923
|
+
currentOwner
|
|
7924
|
+
);
|
|
7925
|
+
applyServerFilter();
|
|
7926
|
+
renderApps3();
|
|
7927
|
+
}
|
|
7992
7928
|
async function unpublishApp(appId) {
|
|
7993
7929
|
if (!await showConfirm(t("confirm.removePublished"))) return;
|
|
7994
7930
|
var app = null;
|
|
@@ -8020,7 +7956,7 @@
|
|
|
8020
7956
|
delete app.publishedVersionNumber;
|
|
8021
7957
|
delete app.publishedVersionsUrl;
|
|
8022
7958
|
saveApp(app).then(function() {
|
|
8023
|
-
|
|
7959
|
+
loadPublishedApps2();
|
|
8024
7960
|
});
|
|
8025
7961
|
} else {
|
|
8026
7962
|
showNotice("Failed to remove: " + (json.error && json.error.message || "Unknown error"));
|
|
@@ -8046,7 +7982,7 @@
|
|
|
8046
7982
|
}).then(function(json) {
|
|
8047
7983
|
if (json.ok) {
|
|
8048
7984
|
if (getServerState2()[filename]) getServerState2()[filename].parked = !!parked;
|
|
8049
|
-
|
|
7985
|
+
loadPublishedApps2();
|
|
8050
7986
|
refreshServerMgmt();
|
|
8051
7987
|
} else {
|
|
8052
7988
|
showNotice("Failed: " + (json.error && json.error.message ? json.error.message : "Unknown error"));
|
|
@@ -8072,7 +8008,7 @@
|
|
|
8072
8008
|
}).then(function(json) {
|
|
8073
8009
|
if (json.ok) {
|
|
8074
8010
|
if (getServerState2()[filename]) getServerState2()[filename].forkable = !!forkable;
|
|
8075
|
-
|
|
8011
|
+
loadPublishedApps2();
|
|
8076
8012
|
refreshServerMgmt();
|
|
8077
8013
|
} else {
|
|
8078
8014
|
showNotice("Failed: " + (json.error && json.error.message ? json.error.message : "Unknown error"));
|
|
@@ -8099,7 +8035,7 @@
|
|
|
8099
8035
|
return resp.json();
|
|
8100
8036
|
}).then(function(json) {
|
|
8101
8037
|
if (json.ok) {
|
|
8102
|
-
|
|
8038
|
+
loadPublishedApps2();
|
|
8103
8039
|
} else {
|
|
8104
8040
|
showNotice("Failed to delete: " + (json.error && json.error.message ? json.error.message : "Unknown error"));
|
|
8105
8041
|
}
|
|
@@ -8158,7 +8094,7 @@
|
|
|
8158
8094
|
}
|
|
8159
8095
|
function filterByTag(tag) {
|
|
8160
8096
|
setActiveTag(tag);
|
|
8161
|
-
|
|
8097
|
+
renderApps4();
|
|
8162
8098
|
applyServerFilter();
|
|
8163
8099
|
}
|
|
8164
8100
|
function launchApp2(id, mode) {
|
|
@@ -8232,7 +8168,7 @@
|
|
|
8232
8168
|
}
|
|
8233
8169
|
}
|
|
8234
8170
|
function buildLibraryEntries(localApps, serverApps) {
|
|
8235
|
-
var
|
|
8171
|
+
var base3 = (loadConfig().aimeatUrl || "").replace(/\/+$/, "");
|
|
8236
8172
|
var byFilename = {};
|
|
8237
8173
|
var entries = [];
|
|
8238
8174
|
serverStateByFilename = {};
|
|
@@ -8262,7 +8198,7 @@
|
|
|
8262
8198
|
filename: la.publishedFilename || null,
|
|
8263
8199
|
owner: null,
|
|
8264
8200
|
versionNumber: la.publishedVersionNumber || null,
|
|
8265
|
-
viewUrl: la.publishedUrl ?
|
|
8201
|
+
viewUrl: la.publishedUrl ? base3 + la.publishedUrl : "",
|
|
8266
8202
|
forkable: false,
|
|
8267
8203
|
forks: 0
|
|
8268
8204
|
};
|
|
@@ -8285,7 +8221,7 @@
|
|
|
8285
8221
|
m.hasDraft = !!sa.has_draft;
|
|
8286
8222
|
m.hasAgents = shipsAgent;
|
|
8287
8223
|
m.protection = prot;
|
|
8288
|
-
m.viewUrl =
|
|
8224
|
+
m.viewUrl = base3 + "/v1/apps/" + encodeURIComponent(sa.owner || "") + "/" + encodeURIComponent(fn);
|
|
8289
8225
|
if (!m.description && sa.manifest && sa.manifest.description) m.description = sa.manifest.description;
|
|
8290
8226
|
} else {
|
|
8291
8227
|
var se = {
|
|
@@ -8294,6 +8230,7 @@
|
|
|
8294
8230
|
name: sa.manifest && sa.manifest.name || fn,
|
|
8295
8231
|
icon: "🌐",
|
|
8296
8232
|
description: sa.manifest && sa.manifest.description || "",
|
|
8233
|
+
descriptions: sa.manifest && sa.manifest.descriptions || null,
|
|
8297
8234
|
tags: sa.manifest && sa.manifest.tags || [],
|
|
8298
8235
|
favorite: false,
|
|
8299
8236
|
sortOrder: void 0,
|
|
@@ -8309,7 +8246,7 @@
|
|
|
8309
8246
|
filename: fn,
|
|
8310
8247
|
owner: sa.owner || "",
|
|
8311
8248
|
versionNumber: sa.version_number || null,
|
|
8312
|
-
viewUrl:
|
|
8249
|
+
viewUrl: base3 && fn ? base3 + "/v1/apps/" + encodeURIComponent(sa.owner || "") + "/" + encodeURIComponent(fn) : "",
|
|
8313
8250
|
forkable: !!sa.forkable,
|
|
8314
8251
|
forks: sa.forks || 0,
|
|
8315
8252
|
protection: prot,
|
|
@@ -8335,20 +8272,12 @@
|
|
|
8335
8272
|
}
|
|
8336
8273
|
return entries;
|
|
8337
8274
|
}
|
|
8338
|
-
function
|
|
8275
|
+
function renderApps4() {
|
|
8339
8276
|
getAllApps().then(function(apps) {
|
|
8340
8277
|
setAllApps(apps);
|
|
8341
|
-
var entries = buildLibraryEntries(
|
|
8278
|
+
var entries = buildLibraryEntries([], ownServerApps);
|
|
8342
8279
|
entries.sort(function(a, b) {
|
|
8343
|
-
if (a.
|
|
8344
|
-
if (!a.favorite && b.favorite) return 1;
|
|
8345
|
-
var oA = typeof a.sortOrder === "number" ? a.sortOrder : Infinity;
|
|
8346
|
-
var oB = typeof b.sortOrder === "number" ? b.sortOrder : Infinity;
|
|
8347
|
-
if (oA !== oB) return oA - oB;
|
|
8348
|
-
var dateA = a.lastOpenedAt || a.addedAt || "";
|
|
8349
|
-
var dateB = b.lastOpenedAt || b.addedAt || "";
|
|
8350
|
-
if (dateA > dateB) return -1;
|
|
8351
|
-
if (dateA < dateB) return 1;
|
|
8280
|
+
if (!!a.parked !== !!b.parked) return a.parked ? 1 : -1;
|
|
8352
8281
|
return 0;
|
|
8353
8282
|
});
|
|
8354
8283
|
var filtered = entries;
|
|
@@ -8397,14 +8326,8 @@
|
|
|
8397
8326
|
grid.innerHTML = html;
|
|
8398
8327
|
}
|
|
8399
8328
|
var statsEl = document.getElementById("stats");
|
|
8400
|
-
|
|
8401
|
-
for (var sz = 0; sz < entries.length; sz++) {
|
|
8402
|
-
if (entries[sz].blob) totalSize += entries[sz].blob.length;
|
|
8403
|
-
}
|
|
8404
|
-
var sizeLabel = totalSize < 1024 ? totalSize + " B" : totalSize < 1048576 ? (totalSize / 1024).toFixed(1) + " KB" : (totalSize / 1048576).toFixed(1) + " MB";
|
|
8405
|
-
statsEl.textContent = entries.length + " " + t("stats.apps") + " · " + sizeLabel + " " + t("stats.stored");
|
|
8329
|
+
statsEl.textContent = entries.length + " " + t("stats.apps");
|
|
8406
8330
|
renderTags();
|
|
8407
|
-
renderRecentlyOpened();
|
|
8408
8331
|
});
|
|
8409
8332
|
}
|
|
8410
8333
|
function libraryCardHtml(e, i) {
|
|
@@ -8416,25 +8339,11 @@
|
|
|
8416
8339
|
var st = libStatus(e);
|
|
8417
8340
|
var dragAttrs = e.hasLocal ? ' draggable="true" ondragstart="window._launcher.onCardDragStart(event)" ondragend="window._launcher.onCardDragEnd(event)" ondragover="window._launcher.onCardDragOver(event)" ondrop="window._launcher.onCardDrop(event)"' : "";
|
|
8418
8341
|
var menuBtn = e.hasLocal ? `<button class="card-menu-btn" onclick="event.stopPropagation(); window._launcher.showContextMenu(event, '` + jsArg(e.localId) + `')" title="` + escapeHtml(t("common.menu")) + '">⋮</button>' : "";
|
|
8419
|
-
return '<div class="app-card' + (e.hasLocal ? "" : " server-only") + '" data-id="' + idAttr + '"' + dragAttrs + filterAttr(e.name, e.tags) + ' onclick="' + detailCall + '"' + (e.hasLocal ? ` oncontextmenu="window._launcher.showContextMenu(event, '` + jsArg(e.localId) + `')"` : "") + ' style="animation-delay:' + i * 0.04 + 's"><span class="app-status-badge st-' + st + '">' + escapeHtml(libStatusLabel(e)) + "</span>" + (e.hasDraft ? '<span class="app-staging-badge" title="' + escapeHtml(t("card.stagingHint")) + '">' + escapeHtml(t("card.stagingBadge")) + "</span>" : "") + menuBtn + '<div class="app-icon">' + escapeHtml(e.icon || "📝") + '</div><div class="app-name">' + escapeHtml(e.name) + (e.origin === "ai-published" ? ' <span class="ai-origin-badge">AI</span>' : "") + (e.hasAgents ? ' <span class="pcb-agent" title="' + escapeHtml(t("card.agentHint")) + '">🤖</span>' : "") + "</div>" + (
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
var recent = getMainApps4().filter(function(a) {
|
|
8425
|
-
return a.lastOpenedAt;
|
|
8426
|
-
}).sort(function(a, b) {
|
|
8427
|
-
return (b.lastOpenedAt || "") > (a.lastOpenedAt || "") ? 1 : -1;
|
|
8428
|
-
}).slice(0, 5);
|
|
8429
|
-
if (recent.length === 0) {
|
|
8430
|
-
section.style.display = "none";
|
|
8431
|
-
return;
|
|
8432
|
-
}
|
|
8433
|
-
section.style.display = "block";
|
|
8434
|
-
strip.innerHTML = recent.map(function(app) {
|
|
8435
|
-
var icon = app.icon || "📝";
|
|
8436
|
-
return `<div style="background:var(--surface-glass);border:1px solid var(--border-subtle);border-radius:10px;padding:.6rem .8rem;cursor:pointer;min-width:120px;flex-shrink:0;transition:all .15s" onclick="window._launcher.launchApp('` + escapeHtml(app.id) + "', '" + escapeHtml(app.openMode || "tab") + `')" onmouseover="this.style.borderColor='var(--border-hover)'" onmouseout="this.style.borderColor='var(--border-subtle)'"><div style="font-size:1.3rem;text-align:center">` + escapeHtml(icon) + '</div><div style="font-size:.75rem;font-weight:600;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100px">' + escapeHtml(app.name) + "</div></div>";
|
|
8437
|
-
}).join("");
|
|
8342
|
+
return '<div class="app-card' + (e.hasLocal ? "" : " server-only") + '" data-id="' + idAttr + '"' + dragAttrs + filterAttr(e.name, e.tags) + ' onclick="' + detailCall + '"' + (e.hasLocal ? ` oncontextmenu="window._launcher.showContextMenu(event, '` + jsArg(e.localId) + `')"` : "") + ' style="animation-delay:' + i * 0.04 + 's"><span class="app-status-badge st-' + st + '">' + escapeHtml(libStatusLabel(e)) + "</span>" + (e.hasDraft ? '<span class="app-staging-badge" title="' + escapeHtml(t("card.stagingHint")) + '">' + escapeHtml(t("card.stagingBadge")) + "</span>" : "") + menuBtn + '<div class="app-icon">' + escapeHtml(e.icon || "📝") + '</div><div class="app-name">' + escapeHtml(e.name) + (e.origin === "ai-published" ? ' <span class="ai-origin-badge">AI</span>' : "") + (e.hasAgents ? ' <span class="pcb-agent" title="' + escapeHtml(t("card.agentHint")) + '">🤖</span>' : "") + "</div>" + (function() {
|
|
8343
|
+
var d = e.descriptions && e.descriptions[getLang()] || e.description || "";
|
|
8344
|
+
return d ? '<div class="app-source">' + escapeHtml(d) + "</div>" : '<div class="app-source">' + sourceLabel(e.source) + "</div>";
|
|
8345
|
+
})() + '<div class="app-actions">' + openBtns + '<button onclick="event.stopPropagation(); ' + detailCall + '">' + escapeHtml(t("ctx.details")) + "</button></div>" + // Server-backed favourite toggle (owner/filename); only for server apps with a filename.
|
|
8346
|
+
(e.filename ? favStarHtml((e.owner || e.aimeatOwner || "") + "/" + e.filename) : "") + "</div>";
|
|
8438
8347
|
}
|
|
8439
8348
|
var currentIframeUrl = "";
|
|
8440
8349
|
function closeIframe() {
|
|
@@ -8496,24 +8405,12 @@
|
|
|
8496
8405
|
openDetailView(appId);
|
|
8497
8406
|
break;
|
|
8498
8407
|
case "edit":
|
|
8499
|
-
|
|
8500
|
-
document.getElementById("modal-title").textContent = "Edit App";
|
|
8501
|
-
document.getElementById("app-name").value = app.name || "";
|
|
8502
|
-
document.getElementById("app-icon").value = app.icon || "";
|
|
8503
|
-
document.getElementById("app-tags").value = (app.tags || []).join(", ");
|
|
8504
|
-
if (app.source === "url") {
|
|
8505
|
-
switchTab("url");
|
|
8506
|
-
document.getElementById("app-url").value = app.url || "";
|
|
8507
|
-
} else {
|
|
8508
|
-
switchTab("file");
|
|
8509
|
-
document.getElementById("selected-file-name").textContent = "(existing file)";
|
|
8510
|
-
}
|
|
8511
|
-
document.getElementById("modal-overlay").hidden = false;
|
|
8408
|
+
openDetailView(appId);
|
|
8512
8409
|
break;
|
|
8513
8410
|
case "favorite":
|
|
8514
8411
|
app.favorite = !app.favorite;
|
|
8515
8412
|
saveApp(app).then(function() {
|
|
8516
|
-
|
|
8413
|
+
renderApps4();
|
|
8517
8414
|
});
|
|
8518
8415
|
break;
|
|
8519
8416
|
case "view-source":
|
|
@@ -8524,13 +8421,13 @@
|
|
|
8524
8421
|
return app.name || "this app";
|
|
8525
8422
|
}))) {
|
|
8526
8423
|
deleteApp(appId).then(function() {
|
|
8527
|
-
|
|
8528
|
-
|
|
8424
|
+
renderApps4();
|
|
8425
|
+
loadPublishedApps2();
|
|
8529
8426
|
});
|
|
8530
8427
|
}
|
|
8531
8428
|
break;
|
|
8532
8429
|
case "publish":
|
|
8533
|
-
|
|
8430
|
+
showPublishModal3(appId);
|
|
8534
8431
|
break;
|
|
8535
8432
|
case "improve-ai":
|
|
8536
8433
|
openPromptBuilder(app);
|
|
@@ -8622,58 +8519,107 @@
|
|
|
8622
8519
|
overlay.dataset.appName = "Homepage";
|
|
8623
8520
|
overlay.hidden = false;
|
|
8624
8521
|
}
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
for (var i = 0; i < cards.length; i++) cards[i].classList.remove("drag-over");
|
|
8639
|
-
dragSourceId = null;
|
|
8640
|
-
}
|
|
8641
|
-
function onCardDragOver(e) {
|
|
8642
|
-
e.preventDefault();
|
|
8643
|
-
e.dataTransfer.dropEffect = "move";
|
|
8644
|
-
var card = e.target.closest(".app-card");
|
|
8645
|
-
if (!card || card.dataset.id === dragSourceId) return;
|
|
8646
|
-
var cards = document.querySelectorAll(".app-card.drag-over");
|
|
8647
|
-
for (var i = 0; i < cards.length; i++) cards[i].classList.remove("drag-over");
|
|
8648
|
-
card.classList.add("drag-over");
|
|
8649
|
-
}
|
|
8650
|
-
function onCardDrop(e) {
|
|
8651
|
-
e.preventDefault();
|
|
8652
|
-
var targetCard = e.target.closest(".app-card");
|
|
8653
|
-
if (!targetCard) return;
|
|
8654
|
-
var targetId = targetCard.dataset.id;
|
|
8655
|
-
if (!dragSourceId || dragSourceId === targetId) return;
|
|
8656
|
-
var srcIdx = -1, tgtIdx = -1;
|
|
8657
|
-
for (var i = 0; i < getMainApps4().length; i++) {
|
|
8658
|
-
if (getMainApps4()[i].id === dragSourceId) srcIdx = i;
|
|
8659
|
-
if (getMainApps4()[i].id === targetId) tgtIdx = i;
|
|
8522
|
+
|
|
8523
|
+
// src/static/app-catalog/js/migrate.js
|
|
8524
|
+
var DONE_KEY = "appCatalogLocalMigrated";
|
|
8525
|
+
async function legacyDbNames() {
|
|
8526
|
+
var names = ["AppLauncherDB"];
|
|
8527
|
+
try {
|
|
8528
|
+
if (indexedDB.databases) {
|
|
8529
|
+
var list = await indexedDB.databases();
|
|
8530
|
+
list.forEach(function(d) {
|
|
8531
|
+
if (d && d.name && d.name.indexOf("AppLauncherDB") === 0 && names.indexOf(d.name) < 0) names.push(d.name);
|
|
8532
|
+
});
|
|
8533
|
+
}
|
|
8534
|
+
} catch (e) {
|
|
8660
8535
|
}
|
|
8661
|
-
|
|
8662
|
-
|
|
8663
|
-
|
|
8664
|
-
|
|
8665
|
-
|
|
8666
|
-
|
|
8667
|
-
|
|
8536
|
+
return names;
|
|
8537
|
+
}
|
|
8538
|
+
function openExisting(name) {
|
|
8539
|
+
return new Promise(function(resolve) {
|
|
8540
|
+
var req;
|
|
8541
|
+
try {
|
|
8542
|
+
req = indexedDB.open(name);
|
|
8543
|
+
} catch (e) {
|
|
8544
|
+
resolve(null);
|
|
8545
|
+
return;
|
|
8546
|
+
}
|
|
8547
|
+
req.onsuccess = function() {
|
|
8548
|
+
resolve(req.result);
|
|
8549
|
+
};
|
|
8550
|
+
req.onerror = function() {
|
|
8551
|
+
resolve(null);
|
|
8552
|
+
};
|
|
8553
|
+
req.onupgradeneeded = function() {
|
|
8554
|
+
};
|
|
8555
|
+
});
|
|
8556
|
+
}
|
|
8557
|
+
function readApps(db) {
|
|
8558
|
+
return new Promise(function(resolve) {
|
|
8559
|
+
if (!db || !db.objectStoreNames || !db.objectStoreNames.contains("apps")) {
|
|
8560
|
+
resolve([]);
|
|
8561
|
+
return;
|
|
8562
|
+
}
|
|
8563
|
+
try {
|
|
8564
|
+
var tx = db.transaction("apps", "readonly");
|
|
8565
|
+
var r = tx.objectStore("apps").getAll();
|
|
8566
|
+
r.onsuccess = function() {
|
|
8567
|
+
resolve(r.result || []);
|
|
8568
|
+
};
|
|
8569
|
+
r.onerror = function() {
|
|
8570
|
+
resolve([]);
|
|
8571
|
+
};
|
|
8572
|
+
} catch (e) {
|
|
8573
|
+
resolve([]);
|
|
8574
|
+
}
|
|
8575
|
+
});
|
|
8576
|
+
}
|
|
8577
|
+
function downloadJson(apps) {
|
|
8578
|
+
var json = JSON.stringify({ version: 1, exportedAt: (/* @__PURE__ */ new Date()).toISOString(), apps }, null, 2);
|
|
8579
|
+
var blob = new Blob([json], { type: "application/json" });
|
|
8580
|
+
var url = URL.createObjectURL(blob);
|
|
8581
|
+
var a = document.createElement("a");
|
|
8582
|
+
a.href = url;
|
|
8583
|
+
a.download = "app-catalog-local-apps.json";
|
|
8584
|
+
document.body.appendChild(a);
|
|
8585
|
+
a.click();
|
|
8586
|
+
document.body.removeChild(a);
|
|
8587
|
+
URL.revokeObjectURL(url);
|
|
8588
|
+
}
|
|
8589
|
+
async function checkLegacyLocalApps() {
|
|
8590
|
+
try {
|
|
8591
|
+
if (localStorage.getItem(DONE_KEY)) return;
|
|
8592
|
+
} catch (e) {
|
|
8593
|
+
return;
|
|
8594
|
+
}
|
|
8595
|
+
var apps = [];
|
|
8596
|
+
try {
|
|
8597
|
+
var names = await legacyDbNames();
|
|
8598
|
+
for (var i = 0; i < names.length; i++) {
|
|
8599
|
+
var db = await openExisting(names[i]);
|
|
8600
|
+
var found = await readApps(db);
|
|
8601
|
+
if (found && found.length) apps = apps.concat(found);
|
|
8602
|
+
try {
|
|
8603
|
+
if (db) db.close();
|
|
8604
|
+
} catch (e) {
|
|
8605
|
+
}
|
|
8606
|
+
}
|
|
8607
|
+
} catch (e) {
|
|
8668
8608
|
}
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8609
|
+
if (!apps.length) {
|
|
8610
|
+
try {
|
|
8611
|
+
localStorage.setItem(DONE_KEY, "1");
|
|
8612
|
+
} catch (e) {
|
|
8613
|
+
}
|
|
8614
|
+
return;
|
|
8615
|
+
}
|
|
8616
|
+
var msg = (t("migrate.found") || "You have {n} local app(s) from the old catalog. Download them as a backup?").replace("{n}", String(apps.length));
|
|
8617
|
+
var wants = await showConfirm(msg);
|
|
8618
|
+
if (wants) downloadJson(apps);
|
|
8619
|
+
try {
|
|
8620
|
+
localStorage.setItem(DONE_KEY, "1");
|
|
8621
|
+
} catch (e) {
|
|
8673
8622
|
}
|
|
8674
|
-
Promise.all(saves).then(function() {
|
|
8675
|
-
renderApps5();
|
|
8676
|
-
});
|
|
8677
8623
|
}
|
|
8678
8624
|
|
|
8679
8625
|
// src/static/app-catalog/js/main.js
|
|
@@ -8687,7 +8633,7 @@
|
|
|
8687
8633
|
}
|
|
8688
8634
|
applyI18n();
|
|
8689
8635
|
try {
|
|
8690
|
-
|
|
8636
|
+
renderApps4();
|
|
8691
8637
|
} catch (e) {
|
|
8692
8638
|
}
|
|
8693
8639
|
try {
|
|
@@ -8695,11 +8641,7 @@
|
|
|
8695
8641
|
} catch (e) {
|
|
8696
8642
|
}
|
|
8697
8643
|
try {
|
|
8698
|
-
|
|
8699
|
-
} catch (e) {
|
|
8700
|
-
}
|
|
8701
|
-
try {
|
|
8702
|
-
renderRecentlyOpened();
|
|
8644
|
+
loadPublishedApps2();
|
|
8703
8645
|
} catch (e) {
|
|
8704
8646
|
}
|
|
8705
8647
|
try {
|
|
@@ -8711,41 +8653,16 @@
|
|
|
8711
8653
|
} catch (e) {
|
|
8712
8654
|
}
|
|
8713
8655
|
}
|
|
8714
|
-
function switchDbMode(mode) {
|
|
8715
|
-
if (mode === getDbMode()) return;
|
|
8716
|
-
if (mode === "personal" && !currentOwnerName()) {
|
|
8717
|
-
updateModeToggle2();
|
|
8718
|
-
requireSignInThen(function() {
|
|
8719
|
-
switchDbMode("personal");
|
|
8720
|
-
});
|
|
8721
|
-
return;
|
|
8722
|
-
}
|
|
8723
|
-
setDbMode(mode);
|
|
8724
|
-
closeDbInstance();
|
|
8725
|
-
updateModeToggle2();
|
|
8726
|
-
refreshAll3();
|
|
8727
|
-
}
|
|
8728
|
-
function updateModeToggle2() {
|
|
8729
|
-
var globalBtn = document.getElementById("mode-global");
|
|
8730
|
-
var personalBtn = document.getElementById("mode-personal");
|
|
8731
|
-
if (!globalBtn || !personalBtn) return;
|
|
8732
|
-
globalBtn.classList.toggle("active", getDbMode() === "global");
|
|
8733
|
-
personalBtn.classList.toggle("active", getDbMode() === "personal");
|
|
8734
|
-
var signedIn = !!currentOwnerName();
|
|
8735
|
-
personalBtn.classList.toggle("mode-btn-locked", !signedIn);
|
|
8736
|
-
personalBtn.title = signedIn ? t("mode.personal.title") : t("mode.personal.needsLogin");
|
|
8737
|
-
}
|
|
8738
8656
|
var allApps = [];
|
|
8739
8657
|
var activeTag = null;
|
|
8740
8658
|
var searchQuery = "";
|
|
8741
8659
|
window._launcher = {
|
|
8742
|
-
openDB,
|
|
8743
8660
|
getAllApps,
|
|
8744
8661
|
saveApp,
|
|
8745
8662
|
deleteApp,
|
|
8746
8663
|
loadConfig,
|
|
8747
8664
|
saveConfig,
|
|
8748
|
-
renderApps:
|
|
8665
|
+
renderApps: renderApps4,
|
|
8749
8666
|
renderTags,
|
|
8750
8667
|
filterByTag,
|
|
8751
8668
|
launchApp: launchApp2,
|
|
@@ -8762,10 +8679,6 @@
|
|
|
8762
8679
|
handleContextAction,
|
|
8763
8680
|
generateId,
|
|
8764
8681
|
readFileAsText,
|
|
8765
|
-
addAppFromUrl,
|
|
8766
|
-
addAppFromFile,
|
|
8767
|
-
addAppFromSource,
|
|
8768
|
-
addAppFromZip,
|
|
8769
8682
|
showModal,
|
|
8770
8683
|
closeModal,
|
|
8771
8684
|
openSettings,
|
|
@@ -8774,18 +8687,22 @@
|
|
|
8774
8687
|
saveSettings,
|
|
8775
8688
|
closeSettings,
|
|
8776
8689
|
applyTheme,
|
|
8777
|
-
exportBackup,
|
|
8778
|
-
clearAllData,
|
|
8779
|
-
importFromAimeat,
|
|
8780
|
-
processAimeatImport,
|
|
8781
8690
|
viewSource: viewSource2,
|
|
8782
8691
|
generateHomepagePrompt,
|
|
8783
|
-
showPublishModal:
|
|
8692
|
+
showPublishModal: showPublishModal3,
|
|
8784
8693
|
submitPublish,
|
|
8785
|
-
loadPublishedApps:
|
|
8694
|
+
loadPublishedApps: loadPublishedApps2,
|
|
8695
|
+
// Toggle a server-backed favourite (ref = "owner/filename"), then re-render the ⭐ group + stars.
|
|
8696
|
+
toggleFavorite: function(ref) {
|
|
8697
|
+
toggleFavorite(ref).then(function() {
|
|
8698
|
+
try {
|
|
8699
|
+
refreshFavoritesUI();
|
|
8700
|
+
} catch (e) {
|
|
8701
|
+
}
|
|
8702
|
+
});
|
|
8703
|
+
},
|
|
8786
8704
|
toggleCommunity,
|
|
8787
8705
|
switchView,
|
|
8788
|
-
switchDbMode,
|
|
8789
8706
|
unpublishApp,
|
|
8790
8707
|
deleteServerApp,
|
|
8791
8708
|
toggleParkApp,
|
|
@@ -8793,6 +8710,9 @@
|
|
|
8793
8710
|
detailAboutEdit,
|
|
8794
8711
|
detailAboutCancel,
|
|
8795
8712
|
detailAboutSave,
|
|
8713
|
+
detailTranslateDesc,
|
|
8714
|
+
detailPromoteSave,
|
|
8715
|
+
detailPromoteClear,
|
|
8796
8716
|
detailToggleFavorite,
|
|
8797
8717
|
detailAccessCodeEdit,
|
|
8798
8718
|
detailAccessCodeCancel,
|
|
@@ -8812,9 +8732,6 @@
|
|
|
8812
8732
|
revokeConsent,
|
|
8813
8733
|
submitSubdomainAssign,
|
|
8814
8734
|
unassignSubdomain,
|
|
8815
|
-
jsonImportSelectAll,
|
|
8816
|
-
submitJsonImport,
|
|
8817
|
-
removeDuplicateApps,
|
|
8818
8735
|
toggleBackupMenu,
|
|
8819
8736
|
toggleCreateMenu,
|
|
8820
8737
|
toggleCortexBar,
|
|
@@ -8850,7 +8767,6 @@
|
|
|
8850
8767
|
detailSetScreenshot,
|
|
8851
8768
|
detailRefreshScreenshot,
|
|
8852
8769
|
openPublishedDetail,
|
|
8853
|
-
renderRecentlyOpened,
|
|
8854
8770
|
loadCortexExtensions,
|
|
8855
8771
|
showCortexPopup,
|
|
8856
8772
|
cortexCopy,
|
|
@@ -8861,10 +8777,6 @@
|
|
|
8861
8777
|
cortexEditorExport,
|
|
8862
8778
|
openPromptBuilder,
|
|
8863
8779
|
closePbPanel,
|
|
8864
|
-
onCardDragStart,
|
|
8865
|
-
onCardDragEnd,
|
|
8866
|
-
onCardDragOver,
|
|
8867
|
-
onCardDrop,
|
|
8868
8780
|
syncConfigToServer,
|
|
8869
8781
|
loadConfigFromServer,
|
|
8870
8782
|
setLanguage,
|
|
@@ -8875,16 +8787,16 @@
|
|
|
8875
8787
|
window.cortexCopy = cortexCopy;
|
|
8876
8788
|
function refreshAll3() {
|
|
8877
8789
|
allApps = [];
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
renderRecentlyOpened();
|
|
8790
|
+
renderApps4();
|
|
8791
|
+
loadPublishedApps2();
|
|
8881
8792
|
}
|
|
8882
8793
|
document.addEventListener("DOMContentLoaded", function() {
|
|
8883
8794
|
initDetail({
|
|
8884
8795
|
refreshAll: refreshAll3,
|
|
8885
|
-
loadPublishedApps:
|
|
8886
|
-
renderApps:
|
|
8887
|
-
updateModeToggle:
|
|
8796
|
+
loadPublishedApps: loadPublishedApps2,
|
|
8797
|
+
renderApps: renderApps4,
|
|
8798
|
+
updateModeToggle: function() {
|
|
8799
|
+
},
|
|
8888
8800
|
getCortexOwnerToken,
|
|
8889
8801
|
launchApp: launchApp2,
|
|
8890
8802
|
viewPublished: viewPublished2,
|
|
@@ -8892,7 +8804,7 @@
|
|
|
8892
8804
|
generateId,
|
|
8893
8805
|
generateSharePrompt: generateSharePrompt2,
|
|
8894
8806
|
openPromptBuilder,
|
|
8895
|
-
showPublishModal:
|
|
8807
|
+
showPublishModal: showPublishModal3,
|
|
8896
8808
|
getMainApps: function() {
|
|
8897
8809
|
return allApps;
|
|
8898
8810
|
},
|
|
@@ -8911,10 +8823,10 @@
|
|
|
8911
8823
|
initAppAgents({ getServerManifests: function() {
|
|
8912
8824
|
return serverAppManifests;
|
|
8913
8825
|
} });
|
|
8914
|
-
initSettings({ generateId, renderApps:
|
|
8915
|
-
initAppsIo({ generateId, readFileAsText, renderApps:
|
|
8826
|
+
initSettings({ generateId, renderApps: renderApps4, loadPublishedApps: loadPublishedApps2 });
|
|
8827
|
+
initAppsIo({ generateId, readFileAsText, renderApps: renderApps4, getMainApps: function() {
|
|
8916
8828
|
return allApps;
|
|
8917
|
-
} });
|
|
8829
|
+
}, showPublishModal: showPublishModal3 });
|
|
8918
8830
|
initServerIo({
|
|
8919
8831
|
getMainApps: function() {
|
|
8920
8832
|
return allApps;
|
|
@@ -8937,7 +8849,7 @@
|
|
|
8937
8849
|
return searchQuery;
|
|
8938
8850
|
},
|
|
8939
8851
|
generateId,
|
|
8940
|
-
renderApps:
|
|
8852
|
+
renderApps: renderApps4,
|
|
8941
8853
|
refreshAll: refreshAll3
|
|
8942
8854
|
});
|
|
8943
8855
|
initRender({
|
|
@@ -8969,7 +8881,6 @@
|
|
|
8969
8881
|
var _urlLang = _params.get("lang");
|
|
8970
8882
|
setLang(_urlLang === "fi" || _urlLang === "en" ? _urlLang : loadConfig().language === "fi" ? "fi" : "en");
|
|
8971
8883
|
applyI18n();
|
|
8972
|
-
updateModeToggle2();
|
|
8973
8884
|
var _savedView = "library";
|
|
8974
8885
|
try {
|
|
8975
8886
|
_savedView = localStorage.getItem("appCatalogView") || "library";
|
|
@@ -8982,8 +8893,8 @@
|
|
|
8982
8893
|
if (_homeLabel && location.host) _homeLabel.textContent = location.host.replace(/^apps\./, "");
|
|
8983
8894
|
} catch (e) {
|
|
8984
8895
|
}
|
|
8985
|
-
|
|
8986
|
-
|
|
8896
|
+
renderApps4();
|
|
8897
|
+
loadPublishedApps2();
|
|
8987
8898
|
loadCortexExtensions();
|
|
8988
8899
|
loadConfigFromServer();
|
|
8989
8900
|
document.getElementById("confirm-ok-btn").addEventListener("click", function() {
|
|
@@ -8995,6 +8906,10 @@
|
|
|
8995
8906
|
document.getElementById("confirm-overlay").addEventListener("click", function(e) {
|
|
8996
8907
|
if (e.target === this) closeConfirm(false);
|
|
8997
8908
|
});
|
|
8909
|
+
try {
|
|
8910
|
+
checkLegacyLocalApps();
|
|
8911
|
+
} catch (e) {
|
|
8912
|
+
}
|
|
8998
8913
|
if (_params.get("create") === "1") {
|
|
8999
8914
|
try {
|
|
9000
8915
|
openPromptBuilder(null);
|
|
@@ -9003,7 +8918,7 @@
|
|
|
9003
8918
|
}
|
|
9004
8919
|
document.getElementById("search-input").addEventListener("input", function(e) {
|
|
9005
8920
|
searchQuery = e.target.value.trim();
|
|
9006
|
-
|
|
8921
|
+
renderApps4();
|
|
9007
8922
|
applyServerFilter();
|
|
9008
8923
|
});
|
|
9009
8924
|
document.getElementById("add-btn").addEventListener("click", function() {
|
|
@@ -9028,17 +8943,6 @@
|
|
|
9028
8943
|
closeSettings();
|
|
9029
8944
|
}
|
|
9030
8945
|
});
|
|
9031
|
-
document.getElementById("import-file-input").addEventListener("change", function() {
|
|
9032
|
-
if (this.files && this.files.length > 0) {
|
|
9033
|
-
handleImportBackup(this.files[0]);
|
|
9034
|
-
this.value = "";
|
|
9035
|
-
}
|
|
9036
|
-
});
|
|
9037
|
-
document.getElementById("aimeat-import-overlay").addEventListener("click", function(e) {
|
|
9038
|
-
if (e.target === this) {
|
|
9039
|
-
this.hidden = true;
|
|
9040
|
-
}
|
|
9041
|
-
});
|
|
9042
8946
|
document.getElementById("publish-overlay").addEventListener("click", function(e) {
|
|
9043
8947
|
if (e.target === this) {
|
|
9044
8948
|
this.hidden = true;
|
|
@@ -9063,11 +8967,6 @@
|
|
|
9063
8967
|
this.hidden = true;
|
|
9064
8968
|
}
|
|
9065
8969
|
});
|
|
9066
|
-
document.getElementById("json-import-overlay").addEventListener("click", function(e) {
|
|
9067
|
-
if (e.target === this) {
|
|
9068
|
-
this.hidden = true;
|
|
9069
|
-
}
|
|
9070
|
-
});
|
|
9071
8970
|
document.addEventListener("click", function(e) {
|
|
9072
8971
|
var menu = document.getElementById("backup-menu");
|
|
9073
8972
|
if (!menu.hidden && !menu.contains(e.target) && e.target.id !== "backup-btn") {
|
|
@@ -9198,16 +9097,12 @@
|
|
|
9198
9097
|
document.getElementById("source-overlay").hidden = true;
|
|
9199
9098
|
} else if (!document.getElementById("context-menu").hidden) {
|
|
9200
9099
|
hideContextMenu();
|
|
9201
|
-
} else if (!document.getElementById("aimeat-import-overlay").hidden) {
|
|
9202
|
-
document.getElementById("aimeat-import-overlay").hidden = true;
|
|
9203
9100
|
} else if (!document.getElementById("publish-overlay").hidden) {
|
|
9204
9101
|
document.getElementById("publish-overlay").hidden = true;
|
|
9205
9102
|
} else if (!document.getElementById("subdomain-overlay").hidden) {
|
|
9206
9103
|
document.getElementById("subdomain-overlay").hidden = true;
|
|
9207
9104
|
} else if (!document.getElementById("backup-overlay").hidden) {
|
|
9208
9105
|
document.getElementById("backup-overlay").hidden = true;
|
|
9209
|
-
} else if (!document.getElementById("json-import-overlay").hidden) {
|
|
9210
|
-
document.getElementById("json-import-overlay").hidden = true;
|
|
9211
9106
|
} else if (!document.getElementById("settings-overlay").hidden) {
|
|
9212
9107
|
closeSettings();
|
|
9213
9108
|
} else if (!document.getElementById("modal-overlay").hidden) {
|
|
@@ -9227,23 +9122,6 @@
|
|
|
9227
9122
|
document.getElementById("search-input").focus();
|
|
9228
9123
|
}
|
|
9229
9124
|
});
|
|
9230
|
-
document.getElementById("app-grid").addEventListener("touchstart", function(e) {
|
|
9231
|
-
var card = e.target.closest(".app-card");
|
|
9232
|
-
if (!card) return;
|
|
9233
|
-
var appId = card.getAttribute("data-id");
|
|
9234
|
-
card._longPressTimer = setTimeout(function() {
|
|
9235
|
-
e.preventDefault();
|
|
9236
|
-
window._launcher.showContextMenu(e.touches[0], appId);
|
|
9237
|
-
}, 500);
|
|
9238
|
-
}, { passive: false });
|
|
9239
|
-
document.getElementById("app-grid").addEventListener("touchend", function(e) {
|
|
9240
|
-
var card = e.target.closest(".app-card");
|
|
9241
|
-
if (card && card._longPressTimer) clearTimeout(card._longPressTimer);
|
|
9242
|
-
});
|
|
9243
|
-
document.getElementById("app-grid").addEventListener("touchmove", function(e) {
|
|
9244
|
-
var card = e.target.closest(".app-card");
|
|
9245
|
-
if (card && card._longPressTimer) clearTimeout(card._longPressTimer);
|
|
9246
|
-
});
|
|
9247
9125
|
document.getElementById("copy-source-btn").addEventListener("click", function() {
|
|
9248
9126
|
var code = document.getElementById("source-code").value;
|
|
9249
9127
|
var btn = this;
|
|
@@ -9314,7 +9192,7 @@
|
|
|
9314
9192
|
btn.textContent = "Save Changes";
|
|
9315
9193
|
btn.disabled = true;
|
|
9316
9194
|
}, 1500);
|
|
9317
|
-
|
|
9195
|
+
renderApps4();
|
|
9318
9196
|
}).catch(function(err) {
|
|
9319
9197
|
btn.textContent = "Save Changes";
|
|
9320
9198
|
btn.disabled = false;
|