Browse Source

enhance(mobile): remove the full ionic components

charlie 4 months ago
parent
commit
bfbf4a5c61

+ 2 - 4
resources/mobile/index.html

@@ -2,9 +2,8 @@
 <html lang="en" data-color="logseq">
 <head>
     <meta charset="UTF-8">
-    <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
-    <link href="./ionic.bundle.css" rel="stylesheet">
-    <link href="./silkhq.css" rel="stylesheet">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+    <link href="./silkhq.css" rel="stylesheet" type="text/css">
     <link href="./style.css" rel="stylesheet" type="text/css">
     <title>Logseq: A privacy-first platform for knowledge management and collaboration</title>
 </head>
@@ -36,7 +35,6 @@ const portal = new MagicPortal(worker);
 <script defer src="./js/tabler.ext.js"></script>
 <script defer src="./js/ui.js"></script>
 <script defer src="./js/amplify.js"></script>
-<script defer src="./ionic.js"></script>
 <script defer src="./silkhq.js"></script>
 <script defer src="./js/shared.js"></script>
 <script defer src="./js/main.js"></script>

+ 1 - 2
src/main/mobile/components/app.cljs

@@ -179,8 +179,7 @@
       (silkhq/depth-sheet-scenery-outlets
         (silkhq/scroll {:as-child true}
           (silkhq/scroll-view
-            {:safeArea "none"
-             :class "silk-scroll-view"
+            {:class "silk-scroll-view"
              :pageScroll true
              :nativePageScrollReplacement true}
             (silkhq/scroll-content {:class "app-silk-index-scroll-content"}

+ 15 - 39
src/main/mobile/components/app.css

@@ -1,3 +1,8 @@
+* {
+  -webkit-tap-highlight-color: transparent; /* Removes the grey highlight on clickable elements on iOS */
+  -webkit-text-size-adjust: 100%; /* Prevent adjustments of font size after orientation changes in iOS */
+}
+
 :root {
   --ls-page-title-size: 26px;
   --silk-topbar-height: 48px;
@@ -9,38 +14,6 @@ html.is-native-ios {
 }
 
 html.is-native-android {
-  --safe-area-inset-top: 46px;
-  --safe-area-inset-bottom: 16px;
-}
-
-html.plt-capacitor.plt-android {
-  --ion-safe-area-top: 42px;
-  --ion-safe-area-bottom: 16px;
-
-  ion-button, ion-tab-button {
-    --ripple-color: rgba(0, 0, 0, .3); /* 设置涟漪颜色为透明 */
-  }
-
-  ion-app {
-    margin-top: 0;
-  }
-
-  .header-md {
-    box-shadow: 0 2px 8px #eee;
-    border-bottom: .5px solid rgba(0, 0, 0, .15);
-  }
-
-  .searchbar-input.sc-ion-searchbar-md {
-    @apply shadow-none;
-  }
-
-  ion-modal {
-    ion-content {
-      #app-container-wrapper {
-        @apply pt-0;
-      }
-    }
-  }
 
   .pswp__top-bar {
     @apply relative top-8;
@@ -373,23 +346,23 @@ html[data-color=logseq] {
 .app-silk-index-container {
   @apply p-4 flex flex-col gap-3 bg-gray-01;
 
-  padding-top: calc(var(--safe-area-inset-top, 0px) + var(--silk-topbar-height) + 10px);
+  padding-top: calc(env(safe-area-inset-top, 0px) + var(--silk-topbar-height) + 10px);
 }
 
 .app-silk-topbar {
   @apply fixed top-0 left-0 w-full border-b bg-gray-02 dark:bg-gray-01
-  justify-between items-center overflow-hidden px-2 grid grid-cols-8 gap-4;
+  justify-between items-center overflow-hidden grid grid-cols-8 gap-4;
 
-  padding-bottom: 10px;
-  padding-top: calc(var(--safe-area-inset-top, 0px) + 10px);
+  padding-top: calc(env(safe-area-inset-top, 0px) + 10px);
   height: 48px;
+  box-sizing: content-box;
 
   &.search {
     @apply hidden;
   }
 
   > .as-left, .as-right {
-    @apply flex items-center col-span-2 gap-2;
+    @apply flex items-center col-span-2 gap-2 px-2;
 
     .ui__button {
       @apply opacity-50 px-1;
@@ -401,7 +374,7 @@ html[data-color=logseq] {
   }
 
   > .as-right {
-    @apply justify-end px-1;
+    @apply justify-end;
   }
 
   > .title {
@@ -411,9 +384,12 @@ html[data-color=logseq] {
 }
 
 .app-silk-tabs {
-  @apply flex items-center h-[54px] border-t overflow-hidden
+  @apply flex border-t overflow-hidden
   bg-gray-02 fixed left-0 bottom-0 w-full z-[1] dark:bg-gray-01;
 
+  padding-top: 4px;
+  padding-bottom: calc(env(safe-area-inset-bottom) + 20px);
+
   > .as-item {
     @apply flex flex-1 flex-col items-center pb-1 transition-opacity;
     @apply opacity-40 active:opacity-70;

+ 22 - 23
src/main/mobile/components/search.cljs

@@ -12,7 +12,6 @@
             [logseq.db :as ldb]
             [logseq.shui.hooks :as hooks]
             [logseq.shui.ui :as shui]
-            [mobile.ionic :as ion]
             [mobile.state :as mobile-state]
             [promesa.core :as p]
             [rum.core :as rum]))
@@ -107,29 +106,29 @@
                            (set-recents! nil))}
               "Clear all")]]
 
-          (ion/list
-            (for [item recents]
-              (ion/item
-                {:on-click #(set-input! item)}
-                [:div.flex.flex-row.items-center.gap-1
-                 (ui/icon "search" {:size 15
-                                    :class "text-muted-foreground"})
-                 item])))]
+          [:ul.px-3
+           (for [item recents]
+             [:li.flex.gap-1
+              {:on-click #(set-input! item)}
+              [:div.flex.flex-row.items-center.gap-1
+               (ui/icon "search" {:size 15
+                                  :class "text-muted-foreground"})
+               item]])]]
 
          [:div.px-4.py-2.text-sm.text-muted-foreground.border-b
           "Recent updates"]])
 
-      (ion/list
-        (for [{:keys [icon text header source-page source-block]} result]
-          (let [block (or source-page source-block)]
-            (ion/item
-              {:on-click (fn []
-                           (mobile-state/open-block-modal! block))}
-              [:div.flex.flex-col.gap-1.py-1
-               (when header
-                 [:div.opacity-50.text-sm
-                  header])
-               [:div.flex.flex-row.items-start.gap-1
-                (when icon (ui/icon icon {:size 15
-                                          :class "text-muted-foreground mt-1"}))
-                [:div text]]]))))]]))
+      [:ul.px-3
+       (for [{:keys [icon text header source-page source-block]} result]
+         (let [block (or source-page source-block)]
+           [:li.flex.gap-1
+            {:on-click (fn []
+                         (mobile-state/open-block-modal! block))}
+            [:div.flex.flex-col.gap-1.py-1
+             (when header
+               [:div.opacity-50.text-sm
+                header])
+             [:div.flex.flex-row.items-start.gap-1
+              (when icon (ui/icon icon {:size 15
+                                        :class "text-muted-foreground mt-1"}))
+              [:div text]]]]))]]]))

+ 29 - 34
src/main/mobile/components/settings.cljs

@@ -6,8 +6,6 @@
             [frontend.state :as state]
             [logseq.shui.ui :as shui]
             [logseq.shui.silkhq :as silkhq]
-            [mobile.components.ui :as ui-component]
-            [mobile.ionic :as ion]
             [rum.core :as rum]))
 
 (rum/defc user-profile
@@ -29,35 +27,32 @@
 (rum/defc page < rum/reactive
   []
   (let [login? (and (state/sub :auth/id-token) (user-handler/logged-in?))]
-    (ion/page
-     (ion/header
-      (ion/toolbar
-       (ion/title "Settings")
-       (let [buttons (->> [(when login?
-                             {:text "Logout" :role "logout"})
-                           {:text "Report bug" :role "report-bug"}]
-                          (remove nil?))]
-         (ion/buttons {:slot "end"}
-                      (ion/button
-                       {:size "small"
-                        :fill "clear"
-                        :on-click (fn [_e]
-                                    (ui-component/open-modal! "Settings"
-                                                              {:type :action-sheet
-                                                               :buttons buttons
-                                                               :inputs []
-                                                               :on-action (fn [e]
-                                                                            (when-let [role (:role e)]
-                                                                              (case role
-                                                                                "logout"
-                                                                                (user-handler/logout)
-                                                                                "report-bug"
-                                                                                (js/window.open "https://github.com/logseq/db-test/issues" "_blank")
-                                                                                nil)))
-                                                               :modal-props {:class "graph-switcher"}}))}
-                       [:span.text-muted-foreground {:slot "icon-only"}
-                        (ion/tabler-icon "dots" {:size 20})])))))
-      (ion/content {:class "ion-padding"}
-        (user-profile login?)
-        [:div.mt-8
-         (repo/repos-cp)]))))
+    ;(let [buttons (->> [(when login?
+    ;                      {:text "Logout" :role "logout"})
+    ;                    {:text "Report bug" :role "report-bug"}]
+    ;                (remove nil?))]
+    ;  (ion/buttons {:slot "end"}
+    ;    (ion/button
+    ;      {:size "small"
+    ;       :fill "clear"
+    ;       :on-click (fn [_e]
+    ;                   (ui-component/open-modal! "Settings"
+    ;                     {:type :action-sheet
+    ;                      :buttons buttons
+    ;                      :inputs []
+    ;                      :on-action (fn [e]
+    ;                                   (when-let [role (:role e)]
+    ;                                     (case role
+    ;                                       "logout"
+    ;                                       (user-handler/logout)
+    ;                                       "report-bug"
+    ;                                       (js/window.open "https://github.com/logseq/db-test/issues" "_blank")
+    ;                                       nil)))
+    ;                      :modal-props {:class "graph-switcher"}}))}
+    ;      [:span.text-muted-foreground {:slot "icon-only"}
+    ;       (ion/tabler-icon "dots" {:size 20})])))
+
+    [:div.app-index-settings
+     (user-profile login?)
+     [:div.mt-8
+      (repo/repos-cp)]]))

+ 90 - 76
src/main/mobile/components/ui.cljs

@@ -5,8 +5,9 @@
             [frontend.handler.notification :as notification]
             [frontend.rum :as r]
             [frontend.state :as state]
+            [logseq.shui.ui :as shui]
+            [logseq.shui.silkhq :as silkhq]
             [medley.core :as medley]
-            [mobile.ionic :as ion]
             [mobile.state :as mobile-state]
             [react-transition-group :refer [CSSTransition TransitionGroup]]
             [rum.core :as rum]))
@@ -25,10 +26,11 @@
   []
   [:div.ui__notifications-content
    [:div.pointer-events-auto.notification-clear
-    (ion/button
-     {:on-click (fn []
-                  (notification/clear-all!))}
-     "clear all")]])
+    (shui/button
+      {:size :sm
+       :on-click (fn []
+                   (notification/clear-all!))}
+      "clear all")]])
 
 (rum/defc notification-content
   [state content status uid]
@@ -37,20 +39,20 @@
           (if (keyword? status)
             (case status
               :success
-              (ion/tabler-icon "circle-check" {:class "text-green-600" :size "20"})
+              (shui/tabler-icon "circle-check" {:class "text-green-600" :size "20"})
 
               :warning
-              (ion/tabler-icon "alert-circle" {:class "text-yellow-600" :size "20"})
+              (shui/tabler-icon "alert-circle" {:class "text-yellow-600" :size "20"})
 
               :error
-              (ion/tabler-icon "circle-x" {:class "text-red-600" :size "20"})
+              (shui/tabler-icon "circle-x" {:class "text-red-600" :size "20"})
 
-              (ion/tabler-icon "info-circle" {:class "text-indigo-600" :size "20"}))
+              (shui/tabler-icon "info-circle" {:class "text-indigo-600" :size "20"}))
             status)]
       [:div.ui__notifications-content
        {:style
         (when (or (= state "exiting")
-                  (= state "exited"))
+                (= state "exited"))
           {:z-index -1})}
        [:div.max-w-sm.w-full.shadow-lg.rounded-lg.pointer-events-auto.notification-area
         {:class (case state
@@ -71,38 +73,37 @@
              content]]
            [:div.flex-shrink-0.flex {:style {:margin-top -9
                                              :margin-right -18}}
-            (ion/button
-             {:fill "clear"
-              :mode "ios"
-              :shape "round"
-              :on-click (fn []
-                          (notification/clear! uid))}
-             [:span {:slot "icon-only"}
-              (ion/tabler-icon "x")])]]]]]])))
+            (shui/button
+              {:variant :icon
+               :size :sm
+               :on-click (fn []
+                           (notification/clear! uid))}
+              [:span {:slot "icon-only"}
+               (shui/tabler-icon "x")])]]]]]])))
 
 (rum/defc install-notifications < rum/reactive
   []
   (let [contents (state/sub :notification/contents)]
     (transition-group
-     {:class-name "notifications ui__notifications"}
-     (let [notifications
-           (map (fn [el]
-                  (let [k (first el)
-                        v (second el)]
-                    (css-transition
-                     {:timeout 100
-                      :key (name k)}
-                     (fn [state]
-                       (notification-content state (:content v) (:status v) k)))))
-                contents)
-           clear-all (when (> (count contents) 3)
-                       (css-transition
-                        {:timeout 100
-                         :k "clear-all"}
-                        (fn [_state]
-                          (notification-clear-all))))
-           items (if clear-all (cons clear-all notifications) notifications)]
-       (doall items)))))
+      {:class-name "notifications ui__notifications"}
+      (let [notifications
+            (map (fn [el]
+                   (let [k (first el)
+                         v (second el)]
+                     (css-transition
+                       {:timeout 100
+                        :key (name k)}
+                       (fn [state]
+                         (notification-content state (:content v) (:status v) k)))))
+              contents)
+            clear-all (when (> (count contents) 3)
+                        (css-transition
+                          {:timeout 100
+                           :k "clear-all"}
+                          (fn [_state]
+                            (notification-clear-all))))
+            items (if clear-all (cons clear-all notifications) notifications)]
+        (doall items)))))
 
 (defonce *modals (atom []))
 (defonce ^:private *id (atom 0))
@@ -113,45 +114,58 @@
   (let [{:keys [class header]} modal-props]
     (case type
       :alert
-      (ion/alert
-       (merge modal-props
-              {:is-open true
-               :header (or title header)
-               :message content
-               :backdropDismiss false
-               :onWillDismiss (fn [^js e]
-                                (when on-action
-                                  (on-action (bean/->clj (.-detail e))))
-                                (close!))
-               :buttons (bean/->js (or buttons (:buttons modal-props)))
-               :inputs (bean/->js (or inputs (:inputs modal-props) []))}))
+      (js/alert
+        (pr-str
+          (merge modal-props
+            {:is-open true
+             :header (or title header)
+             :message content
+             :backdropDismiss false
+             :onWillDismiss (fn [^js e]
+                              (when on-action
+                                (on-action (bean/->clj (.-detail e))))
+                              (close!))
+             :buttons (bean/->js (or buttons (:buttons modal-props)))
+             :inputs (bean/->js (or inputs (:inputs modal-props) []))})))
 
       :action-sheet
-      (ion/action-sheet
-       (merge modal-props
-              {:is-open true
-               :header (or content title header)
-               :onWillDismiss (fn [^js e]
-                                (when on-action
-                                  (on-action (bean/->clj (.-detail e))))
-                                (close!))
-               :buttons (bean/->js (or buttons (:buttons modal-props)))}))
+      (silkhq/bottom-sheet
+        (merge modal-props
+          {:presented true
+           :header (or content title header)
+           ;:onPresentedChange (fn [v?]
+           ;                     (when on-action
+           ;                       (on-action (bean/->clj (.-detail e))))
+           ;                     (close!))
+           ;:buttons (bean/->js (or buttons (:buttons modal-props)))
+           })
+        (silkhq/bottom-sheet-portal
+          (silkhq/bottom-sheet-view {:as-child true})
+          (silkhq/bottom-sheet-content
+            (some-> (or title header) (silkhq/bottom-sheet-title))
+            (silkhq/bottom-sheet-content
+              (if (fn? content)
+                (content) content))
+            )))
 
       ;; default
-      (ion/modal
-       (merge modal-props
-              {:is-open true
-               :onWillDismiss (fn [] (close!))
-               :class (str class (when (not (true? as-page?)) " ion-datetime-button-overlay"))})
-       (if (fn? content)
-         (content) content)))))
+      (silkhq/bottom-sheet
+        (merge modal-props
+          {:presented true
+           :onPresentedChange (fn [v?] (when (false? v?) (close!)))})
+        (silkhq/bottom-sheet-portal
+          (silkhq/bottom-sheet-view {:as-child true}
+            (silkhq/bottom-sheet-backdrop)
+            (silkhq/bottom-sheet-content
+              (if (fn? content)
+                (content) content))))))))
 
 (defn get-modal
   ([] (some-> @*modals last))
   ([id]
    (when id
      (some->> (medley/indexed @*modals)
-              (filter #(= id (:id (second %)))) (first)))))
+       (filter #(= id (:id (second %)))) (first)))))
 
 (defn- upsert-modal!
   [config]
@@ -168,11 +182,11 @@
 (defn open-modal!
   [content & {:keys [id type] :as props}]
   (upsert-modal!
-   (merge props
-          {:id (or id (gen-id))
-           :type (or type :default)                             ;; :alert :confirm :page
-           :as-page? (= type :page)
-           :content content})))
+    (merge props
+      {:id (or id (gen-id))
+       :type (or type :default)                             ;; :alert :confirm :page
+       :as-page? (= type :page)
+       :content content})))
 
 (defn close-modal!
   ([] (some-> @*modals (last) :id (close-modal!)))
@@ -181,13 +195,13 @@
 (defn open-popup!
   [content-fn opts]
   (mobile-state/set-popup!
-   {:open? true
-    :content-fn content-fn
-    :opts opts}))
+    {:open? true
+     :content-fn content-fn
+     :opts opts}))
 
 (defn close-popup! []
   (some-> mobile-state/*popup-data
-          (swap! assoc :open? false)))
+    (swap! assoc :open? false)))
 
 (rum/defc install-modals []
   (let [_ (r/use-atom *modals)]
@@ -196,4 +210,4 @@
            :let [close! #(close-modal! id)
                  props' (assoc props :close! close!)]]
        (x-modal props'
-                (if (fn? content) (content props') content)))]))
+         (if (fn? content) (content props') content)))]))

+ 5 - 5
src/main/mobile/components/ui_silk.cljs

@@ -23,27 +23,27 @@
       {:class (when (= current-tab "home") "active")
        :data-tab "home"}
       (shui/button {:variant :icon}
-        (shui/tabler-icon "home" {:size 23}))
+        (shui/tabler-icon "home" {:size 24}))
       [:small "Journals"]]
      [:span.as-item
       {:class (when (= current-tab "search") "active")
        :data-tab "search"}
       (shui/button {:variant :icon}
-        (shui/tabler-icon "search" {:size 23}))
+        (shui/tabler-icon "search" {:size 24}))
       [:small "Search"]]
      [:span.as-item
       (shui/button {:variant :icon}
-        (shui/tabler-icon "plus" {:size 23}))
+        (shui/tabler-icon "plus" {:size 24}))
       [:small "Quick add"]]
      [:span.as-item
       {:class (when (= current-tab "settings") "active")
        :data-tab "settings"}
       (shui/button {:variant :icon}
-        (shui/tabler-icon "settings" {:size 23}))
+        (shui/tabler-icon "settings" {:size 24}))
       [:small "Settings"]]
      [:span.as-item
       {:class (when (= current-tab "demos") "active")
        :data-tab "demos"}
       (shui/button {:variant :icon}
-        (shui/tabler-icon "bug" {:size 23}))
+        (shui/tabler-icon "bug" {:size 24}))
       [:small "Demos"]]]))