diff --git a/frontend/src/app/main/ui/ds/product/loader.cljs b/frontend/src/app/main/ui/ds/product/loader.cljs index 9df8fa7040..e16d86bf0c 100644 --- a/frontend/src/app/main/ui/ds/product/loader.cljs +++ b/frontend/src/app/main/ui/ds/product/loader.cljs @@ -9,13 +9,58 @@ [app.common.data.macros :as dm] [app.main.style :as stl]) (:require + [app.common.data :as d] [app.common.math :as mth] [app.util.i18n :as i18n :refer [tr]] + [beicon.v2.core :as rx] [rumext.v2 :as mf])) +(def tips + [["loader.tips.01" "title" "message"] + ["loader.tips.02" "title" "message"] + ["loader.tips.03" "title" "message"] + ["loader.tips.04" "title" "message"] + ["loader.tips.05" "title" "message"] + ["loader.tips.06" "title" "message"] + ["loader.tips.07" "title" "message"] + ["loader.tips.08" "title" "message"] + ["loader.tips.09" "title" "message"] + ["loader.tips.10" "title" "message"]]) + + +(defn- get-tips + [] + [{:title (tr "loader.tips.01.title") + :message (tr "loader.tips.01.message")} + {:title (tr "loader.tips.02.title") + :message (tr "loader.tips.02.message")} + {:title (tr "loader.tips.03.title") + :message (tr "loader.tips.03.message")} + {:title (tr "loader.tips.04.title") + :message (tr "loader.tips.04.message")} + {:title (tr "loader.tips.05.title") + :message (tr "loader.tips.05.message")} + {:title (tr "loader.tips.06.title") + :message (tr "loader.tips.06.message")} + {:title (tr "loader.tips.07.title") + :message (tr "loader.tips.07.message")} + {:title (tr "loader.tips.08.title") + :message (tr "loader.tips.08.message")} + {:title (tr "loader.tips.09.title") + :message (tr "loader.tips.09.message")} + {:title (tr "loader.tips.10.title") + :message (tr "loader.tips.10.message")}]) + +(def ^:private + svg:loader-path-1 + "M128.273 0l-3.9 2.77L0 91.078l128.273 91.076 549.075-.006V.008L128.273 0zm20.852 30l498.223.006V152.15l-498.223.007V30zm-25 9.74v102.678l-49.033-34.813-.578-32.64 49.61-35.225z") + +(def ^:private + svg:loader-path-2 + "M134.482 157.147v25l518.57.008.002-25-518.572-.008z") + (mf/defc loader-icon* - {::mf/props :obj - ::mf/private true} + {::mf/private true} [{:keys [width height title] :rest props}] (let [class (stl/css :loader) props (mf/spread-props props {:viewBox "0 0 677.34762 182.15429" @@ -23,14 +68,12 @@ :width width :height height :class class})] - [:> "svg" props + [:> :svg props [:title title] [:g - [:path {:d - "M128.273 0l-3.9 2.77L0 91.078l128.273 91.076 549.075-.006V.008L128.273 0zm20.852 30l498.223.006V152.15l-498.223.007V30zm-25 9.74v102.678l-49.033-34.813-.578-32.64 49.61-35.225z"}] + [:path {:d svg:loader-path-1}] [:path {:class (stl/css :loader-line) - :d - "M134.482 157.147v25l518.57.008.002-25-518.572-.008z"}]]])) + :d svg:loader-path-2}]]])) (def ^:private schema:loader [:map @@ -38,22 +81,42 @@ [:width {:optional true} :int] [:height {:optional true} :int] [:title {:optional true} :string] - [:overlay {:optional true} :boolean]]) + [:overlay {:optional true} :boolean] + [:file-loading {:optional true} :boolean]]) (mf/defc loader* - {::mf/props :obj - ::mf/schema schema:loader} - [{:keys [class width height title overlay children] :rest props}] + {::mf/schema schema:loader} + [{:keys [class width height title overlay children file-loading] :rest props}] + (let [width (or width (when (some? height) (mth/ceil (* height (/ 100 27)))) 100) + height (or height (when (some? width) (mth/ceil (* width (/ 27 100)))) 27) - (let [w (or width (when (some? height) (mth/ceil (* height (/ 100 27)))) 100) - h (or height (when (some? width) (mth/ceil (* width (/ 27 100)))) 27) - class (dm/str (or class "") " " (stl/css-case :wrapper true - :wrapper-overlay overlay)) - title (or title (tr "labels.loading")) - props (mf/spread-props props {:class class})] + class (dm/str (d/nilv class "") " " + (stl/css-case :wrapper true + :wrapper-overlay overlay + :file-loading file-loading)) - [:> "div" props - [:> loader-icon* {:title title - :width w - :height h}] - children])) \ No newline at end of file + title (or title (tr "labels.loading")) + tips (mf/use-memo get-tips) + + tip* (mf/use-state nil) + tip (deref tip*)] + + (mf/with-effect [file-loading tips] + (when file-loading + (let [sub (->> (rx/timer 1000 4000) + (rx/subs! #(reset! tip* (rand-nth tips))))] + (partial rx/dispose! sub)))) + + [:> :div {:class class} + [:div {:class (stl/css :loader-content)} + [:> loader-icon* {:title title + :width width + :height height}] + (when (and file-loading tip) + [:div {:class (stl/css :tips-container)} + [:div {:class (stl/css :tip-title)} + (get tip :title)] + [:div {:class (stl/css :tip-message)} + (get tip :message)]])] + + children])) diff --git a/frontend/src/app/main/ui/ds/product/loader.scss b/frontend/src/app/main/ui/ds/product/loader.scss index 1259727394..4eb1f3abde 100644 --- a/frontend/src/app/main/ui/ds/product/loader.scss +++ b/frontend/src/app/main/ui/ds/product/loader.scss @@ -21,8 +21,50 @@ display: inline-flex; column-gap: var(--sp-s); align-items: center; - color: var(--loader-color-foreground); + + // Specific styles for file loading screen + &.file-loading { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; + padding: var(--sp-xxl); + + // Container for loader icon and tips + .loader-content { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--sp-xl); + } + + // Tips container + .tips-container { + text-align: center; + min-width: var(--sp-600); + max-width: var(--sp-800); + display: flex; + flex-direction: column; + gap: var(--sp-s); + border: 1px solid var(--color-background-tertiary); + border-radius: var(--sp-l); + padding: var(--sp-xxl) var(--sp-xxxl); + + // Tips title + .tip-title { + color: var(--color-foreground-primary); + font-weight: 500; + } + + // Tips message + .tip-message { + color: var(--color-foreground-secondary); + } + } + } } .wrapper-overlay { diff --git a/frontend/src/app/main/ui/ds/spacing.scss b/frontend/src/app/main/ui/ds/spacing.scss index 46fd5bbaad..577a182358 100644 --- a/frontend/src/app/main/ui/ds/spacing.scss +++ b/frontend/src/app/main/ui/ds/spacing.scss @@ -14,6 +14,8 @@ $_sp-16: px2rem(16); $_sp-20: px2rem(20); $_sp-24: px2rem(24); $_sp-32: px2rem(32); +$_sp-600: px2rem(600); +$_sp-800: px2rem(800); :global(:root) { --sp-xxs: #{$_sp-2}; @@ -24,4 +26,6 @@ $_sp-32: px2rem(32); --sp-xl: #{$_sp-20}; --sp-xxl: #{$_sp-24}; --sp-xxxl: #{$_sp-32}; + --sp-600: #{$_sp-600}; + --sp-800: #{$_sp-800}; } diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index 3d19f2934e..d6de04f207 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -117,7 +117,8 @@ [] [:> loader* {:title (tr "labels.loading") :class (stl/css :workspace-loader) - :overlay true}]) + :overlay true + :file-loading true}]) (mf/defc workspace-page* {::mf/private true} diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 314a555990..df13275781 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -7127,4 +7127,64 @@ msgid "dashboard.mark-all-as-read.success" msgstr "Marked all notifications as read" msgid "label.mark-all-as-read" -msgstr "Mark all as read" \ No newline at end of file +msgstr "Mark all as read" + +msgid "loader.tips.01.title" +msgstr "Reusable Components" + +msgid "loader.tips.01.message" +msgstr "Keep your designs consistent and easy to update across projects." + +msgid "loader.tips.02.title" +msgstr "Real-time Collaboration" + +msgid "loader.tips.02.message" +msgstr "Work with your team live, share feedback instantly." + +msgid "loader.tips.03.title" +msgstr "Auto Layout like CSS" + +msgid "loader.tips.03.message" +msgstr "Design flexibly with familiar CSS-like layout controls." + +msgid "loader.tips.04.title" +msgstr "Export to Code" + +msgid "loader.tips.04.message" +msgstr "Get CSS and SVG code directly from your designs." + +msgid "loader.tips.05.title" +msgstr "Design Libraries" + +msgid "loader.tips.05.message" +msgstr "Share assets and styles to maintain consistency." + +msgid "loader.tips.06.title" +msgstr "Interactive Prototypes" + +msgid "loader.tips.06.message" +msgstr "Bring your ideas to life with animations and transitions." + +msgid "loader.tips.07.title" +msgstr "Web-Standard Formats" + +msgid "loader.tips.07.message" +msgstr "Penpot uses SVG and CSS for seamless development." + +msgid "loader.tips.08.title" +msgstr "Keyboard Shortcuts" + +msgid "loader.tips.08.message" +msgstr "Speed up your workflow with handy shortcuts like Shift + A for Auto Layout." + +msgid "loader.tips.09.title" +msgstr "Dark & Light Mode" + +msgid "loader.tips.09.message" +msgstr "Choose the theme that suits your style." + +msgid "loader.tips.10.title" +msgstr "Plugins Support" + +msgid "loader.tips.10.message" +msgstr "Extend Penpot with community-built plugins for extra functionality." diff --git a/frontend/translations/es.po b/frontend/translations/es.po index a610d8b510..56e0136e38 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -7118,4 +7118,67 @@ msgid "dashboard.mark-all-as-read.success" msgstr "Se han marcado todas las noficaciones como leídas" msgid "label.mark-all-as-read" -msgstr "Marcar todo como leído" \ No newline at end of file +msgstr "Marcar todo como leído" + +msgid "workspace.versions.tab.actions" +msgstr "Acciones" + +msgid "loader.tips.01.title" +msgstr "Componentes Reutilizables" + +msgid "loader.tips.01.message" +msgstr "Mantén tus diseños consistentes y fáciles de actualizar en todos los proyectos." + +msgid "loader.tips.02.title" +msgstr "Colaboración en Tiempo Real" + +msgid "loader.tips.02.message" +msgstr "Trabaja con tu equipo en vivo, comparte feedback al instante." + +msgid "loader.tips.03.title" +msgstr "Auto Layout como CSS" + +msgid "loader.tips.03.message" +msgstr "Diseña de forma flexible con controles de diseño similares a CSS." + +msgid "loader.tips.04.title" +msgstr "Exportar a Código" + +msgid "loader.tips.04.message" +msgstr "Obtén código CSS y SVG directamente de tus diseños." + +msgid "loader.tips.05.title" +msgstr "Bibliotecas de Diseño" + +msgid "loader.tips.05.message" +msgstr "Comparte recursos y estilos para mantener la consistencia." + +msgid "loader.tips.06.title" +msgstr "Prototipos Interactivos" + +msgid "loader.tips.06.message" +msgstr "Da vida a tus ideas con animaciones y transiciones." + +msgid "loader.tips.07.title" +msgstr "Formatos Web Estándar" + +msgid "loader.tips.07.message" +msgstr "Penpot usa SVG y CSS para un desarrollo sin problemas." + +msgid "loader.tips.08.title" +msgstr "Atajos de Teclado" + +msgid "loader.tips.08.message" +msgstr "Acelera tu flujo de trabajo con atajos útiles como Shift + A para Auto Layout." + +msgid "loader.tips.09.title" +msgstr "Modo Claro y Oscuro" + +msgid "loader.tips.09.message" +msgstr "Elige el tema que mejor se adapte a tu estilo." + +msgid "loader.tips.10.title" +msgstr "Soporte de Plugins" + +msgid "loader.tips.10.message" +msgstr "Extiende Penpot con plugins creados por la comunidad para funcionalidad extra."