|
874 | 874 | "Simple slideshow viewer without game mechanics" |
875 | 875 | [] |
876 | 876 | (let [lightbox-open? (r/atom false)] |
877 | | - (fn [] |
878 | | - (let [{:keys [current-slide]} @game-state |
879 | | - {:keys [image]} (current-slide-data)] |
880 | | - [:div {:class "trivia-container"} |
881 | | - ;; Lightbox overlay |
882 | | - (when @lightbox-open? |
883 | | - [:div {:style {:position "fixed" |
884 | | - :top 0 |
885 | | - :left 0 |
886 | | - :right 0 |
887 | | - :bottom 0 |
888 | | - :background "rgba(0,0,0,0.95)" |
889 | | - :z-index 9999 |
890 | | - :display "flex" |
891 | | - :align-items "center" |
892 | | - :justify-content "center" |
893 | | - :cursor "pointer" |
894 | | - :animation "fadeIn 0.2s ease"} |
895 | | - :on-click #(reset! lightbox-open? false)} |
896 | | - [:div {:style {:position "relative" |
897 | | - :max-width "95vw" |
898 | | - :max-height "95vh"}} |
899 | | - [:img {:src image |
900 | | - :alt "Conference photo - full size" |
901 | | - :style {:max-width "95vw" |
902 | | - :max-height "95vh" |
903 | | - :object-fit "contain" |
904 | | - :image-orientation "from-image"}}] |
905 | | - [:div {:style {:position "absolute" |
906 | | - :top "10px" |
907 | | - :right "10px" |
908 | | - :background "rgba(255,255,255,0.9)" |
909 | | - :color "#333" |
910 | | - :border "none" |
911 | | - :border-radius "50%" |
912 | | - :width "40px" |
913 | | - :height "40px" |
| 877 | + (r/create-class |
| 878 | + {:component-did-mount |
| 879 | + (fn [this] |
| 880 | + (let [handle-key (fn [e] |
| 881 | + (let [key (.-key e)] |
| 882 | + (case key |
| 883 | + "ArrowLeft" (do (.preventDefault e) |
| 884 | + (when (> (:current-slide @game-state) 0) |
| 885 | + (previous-slide))) |
| 886 | + "ArrowRight" (do (.preventDefault e) |
| 887 | + (when (< (:current-slide @game-state) (dec (total-slides))) |
| 888 | + (next-slide))) |
| 889 | + "Escape" (when @lightbox-open? |
| 890 | + (.preventDefault e) |
| 891 | + (reset! lightbox-open? false)) |
| 892 | + nil)))] |
| 893 | + (js/document.addEventListener "keydown" handle-key) |
| 894 | + (aset this "keyHandler" handle-key))) |
| 895 | + |
| 896 | + :component-will-unmount |
| 897 | + (fn [this] |
| 898 | + (when-let [handler (aget this "keyHandler")] |
| 899 | + (js/document.removeEventListener "keydown" handler))) |
| 900 | + |
| 901 | + :reagent-render |
| 902 | + (fn [] |
| 903 | + (let [{:keys [current-slide]} @game-state |
| 904 | + {:keys [image]} (current-slide-data)] |
| 905 | + [:div {:class "trivia-container"} |
| 906 | + ;; Lightbox overlay |
| 907 | + (when @lightbox-open? |
| 908 | + [:div {:style {:position "fixed" |
| 909 | + :top 0 |
| 910 | + :left 0 |
| 911 | + :right 0 |
| 912 | + :bottom 0 |
| 913 | + :background "rgba(0,0,0,0.95)" |
| 914 | + :z-index 9999 |
914 | 915 | :display "flex" |
915 | 916 | :align-items "center" |
916 | 917 | :justify-content "center" |
917 | | - :font-size "24px" |
918 | 918 | :cursor "pointer" |
919 | | - :font-weight "bold"}} |
920 | | - "×"]]]) |
921 | | - |
922 | | - ;; Title |
923 | | - [:div {:style {:text-align "center" |
924 | | - :margin-bottom "30px"}} |
925 | | - [:h1 {:class "game-title" |
926 | | - :style {:color "#2196f3" |
927 | | - :font-size "32px" |
928 | | - :margin-bottom "10px"}} |
929 | | - "🖼️ Clojure Conj 2025 Photo Gallery"] |
930 | | - [:p {:class "game-subtitle" |
931 | | - :style {:color "#666" |
932 | | - :font-size "16px"}} |
933 | | - "Browse through conference memories"]] |
934 | | - |
935 | | - [:div {:class "trivia-card"} |
936 | | - ;; Image section - full width |
937 | | - [:div {:style {:display "flex" |
938 | | - :align-items "center" |
939 | | - :justify-content "center" |
940 | | - :padding "40px" |
941 | | - :min-height "500px"}} |
942 | | - [:img {:src image |
943 | | - :alt "Conference photo" |
944 | | - :on-click #(reset! lightbox-open? true) |
945 | | - :style {:max-width "100%" |
946 | | - :max-height "600px" |
947 | | - :border-radius "12px" |
948 | | - :box-shadow "0 4px 12px rgba(0,0,0,0.15)" |
949 | | - :object-fit "contain" |
950 | | - :image-orientation "from-image" |
951 | | - :cursor "pointer" |
952 | | - :transition "transform 0.2s ease, box-shadow 0.2s ease"} |
953 | | - :on-mouse-enter #(do |
954 | | - (set! (.. % -target -style -transform) "scale(1.02)") |
955 | | - (set! (.. % -target -style -boxShadow) "0 8px 24px rgba(0,0,0,0.25)")) |
956 | | - :on-mouse-leave #(do |
957 | | - (set! (.. % -target -style -transform) "scale(1)") |
958 | | - (set! (.. % -target -style -boxShadow) "0 4px 12px rgba(0,0,0,0.15)"))}]] |
959 | | - |
960 | | - ;; Navigation |
961 | | - [:div {:class "trivia-nav" |
962 | | - :style {:padding "20px" |
963 | | - :border-top "1px solid #e0e0e0"}} |
964 | | - [:div {:style {:text-align "center" |
965 | | - :margin-bottom "15px"}} |
966 | | - [:p {:class "trivia-slide-info"} |
967 | | - (str "Photo " (inc current-slide) " of " (total-slides))] |
968 | | - [:p {:style {:margin "5px 0 0 0" |
969 | | - :font-size "13px" |
970 | | - :color "#999" |
971 | | - :font-style "italic"}} |
972 | | - "Click image to view full size"]] |
973 | | - |
974 | | - [:div {:style {:display "flex" |
975 | | - :justify-content "space-between" |
976 | | - :gap "15px"}} |
977 | | - [:button {:on-click previous-slide |
978 | | - :disabled (= current-slide 0) |
979 | | - :style {:padding "12px 24px" |
980 | | - :background (if (= current-slide 0) "#e0e0e0" "#2196f3") |
981 | | - :color (if (= current-slide 0) "#999" "white") |
| 919 | + :animation "fadeIn 0.2s ease"} |
| 920 | + :on-click #(reset! lightbox-open? false)} |
| 921 | + [:div {:style {:position "relative" |
| 922 | + :max-width "95vw" |
| 923 | + :max-height "95vh"}} |
| 924 | + [:img {:src image |
| 925 | + :alt "Conference photo - full size" |
| 926 | + :style {:max-width "95vw" |
| 927 | + :max-height "95vh" |
| 928 | + :object-fit "contain" |
| 929 | + :image-orientation "from-image"}}] |
| 930 | + [:div {:style {:position "absolute" |
| 931 | + :top "10px" |
| 932 | + :right "10px" |
| 933 | + :background "rgba(255,255,255,0.9)" |
| 934 | + :color "#333" |
982 | 935 | :border "none" |
983 | | - :border-radius "6px" |
984 | | - :cursor (if (= current-slide 0) "not-allowed" "pointer") |
985 | | - :font-weight "600" |
986 | | - :font-size "16px" |
987 | | - :flex "1"}} |
988 | | - "← Previous"] |
989 | | - |
990 | | - [:button {:on-click back-to-menu |
991 | | - :style {:padding "12px 24px" |
992 | | - :background "#757575" |
993 | | - :color "white" |
994 | | - :border "none" |
995 | | - :border-radius "6px" |
| 936 | + :border-radius "50%" |
| 937 | + :width "40px" |
| 938 | + :height "40px" |
| 939 | + :display "flex" |
| 940 | + :align-items "center" |
| 941 | + :justify-content "center" |
| 942 | + :font-size "24px" |
996 | 943 | :cursor "pointer" |
997 | | - :font-weight "600" |
998 | | - :font-size "16px" |
999 | | - :flex "0 0 auto"}} |
1000 | | - "🏠 Menu"] |
| 944 | + :font-weight "bold"}} |
| 945 | + "×"]]]) |
1001 | 946 |
|
1002 | | - (if (= current-slide (dec (total-slides))) |
1003 | | - [:button {:on-click back-to-menu |
| 947 | + ;; Title |
| 948 | + [:div {:style {:text-align "center" |
| 949 | + :margin-bottom "30px"}} |
| 950 | + [:h1 {:class "game-title" |
| 951 | + :style {:color "#2196f3" |
| 952 | + :font-size "32px" |
| 953 | + :margin-bottom "10px"}} |
| 954 | + "🖼️ Clojure Conj 2025 Photo Gallery"] |
| 955 | + [:p {:class "game-subtitle" |
| 956 | + :style {:color "#666" |
| 957 | + :font-size "16px"}} |
| 958 | + "Browse through conference memories"]] |
| 959 | + |
| 960 | + [:div {:class "trivia-card"} |
| 961 | + ;; Image section - full width |
| 962 | + [:div {:style {:display "flex" |
| 963 | + :align-items "center" |
| 964 | + :justify-content "center" |
| 965 | + :padding "40px" |
| 966 | + :min-height "500px"}} |
| 967 | + [:img {:src image |
| 968 | + :alt "Conference photo" |
| 969 | + :on-click #(reset! lightbox-open? true) |
| 970 | + :style {:max-width "100%" |
| 971 | + :max-height "600px" |
| 972 | + :border-radius "12px" |
| 973 | + :box-shadow "0 4px 12px rgba(0,0,0,0.15)" |
| 974 | + :object-fit "contain" |
| 975 | + :image-orientation "from-image" |
| 976 | + :cursor "pointer" |
| 977 | + :transition "transform 0.2s ease, box-shadow 0.2s ease"} |
| 978 | + :on-mouse-enter #(do |
| 979 | + (set! (.. % -target -style -transform) "scale(1.02)") |
| 980 | + (set! (.. % -target -style -boxShadow) "0 8px 24px rgba(0,0,0,0.25)")) |
| 981 | + :on-mouse-leave #(do |
| 982 | + (set! (.. % -target -style -transform) "scale(1)") |
| 983 | + (set! (.. % -target -style -boxShadow) "0 4px 12px rgba(0,0,0,0.15)"))}]] |
| 984 | + |
| 985 | + ;; Navigation |
| 986 | + [:div {:class "trivia-nav" |
| 987 | + :style {:padding "20px" |
| 988 | + :border-top "1px solid #e0e0e0"}} |
| 989 | + [:div {:style {:text-align "center" |
| 990 | + :margin-bottom "15px"}} |
| 991 | + [:p {:class "trivia-slide-info"} |
| 992 | + (str "Photo " (inc current-slide) " of " (total-slides))] |
| 993 | + [:p {:style {:margin "5px 0 0 0" |
| 994 | + :font-size "13px" |
| 995 | + :color "#999" |
| 996 | + :font-style "italic"}} |
| 997 | + "Click image to view full size • Use ← → arrow keys to navigate"]] |
| 998 | + |
| 999 | + [:div {:style {:display "flex" |
| 1000 | + :justify-content "space-between" |
| 1001 | + :gap "15px"}} |
| 1002 | + [:button {:on-click previous-slide |
| 1003 | + :disabled (= current-slide 0) |
1004 | 1004 | :style {:padding "12px 24px" |
1005 | | - :background "#4caf50" |
1006 | | - :color "white" |
| 1005 | + :background (if (= current-slide 0) "#e0e0e0" "#2196f3") |
| 1006 | + :color (if (= current-slide 0) "#999" "white") |
1007 | 1007 | :border "none" |
1008 | 1008 | :border-radius "6px" |
1009 | | - :cursor "pointer" |
| 1009 | + :cursor (if (= current-slide 0) "not-allowed" "pointer") |
1010 | 1010 | :font-weight "600" |
1011 | 1011 | :font-size "16px" |
1012 | 1012 | :flex "1"}} |
1013 | | - "✓ Finish"] |
1014 | | - [:button {:on-click next-slide |
| 1013 | + "← Previous"] |
| 1014 | + |
| 1015 | + [:button {:on-click back-to-menu |
1015 | 1016 | :style {:padding "12px 24px" |
1016 | | - :background "#2196f3" |
| 1017 | + :background "#757575" |
1017 | 1018 | :color "white" |
1018 | 1019 | :border "none" |
1019 | 1020 | :border-radius "6px" |
1020 | 1021 | :cursor "pointer" |
1021 | 1022 | :font-weight "600" |
1022 | 1023 | :font-size "16px" |
1023 | | - :flex "1"}} |
1024 | | - "Next →"])]]]])))) |
| 1024 | + :flex "0 0 auto"}} |
| 1025 | + "🏠 Menu"] |
| 1026 | + |
| 1027 | + (if (= current-slide (dec (total-slides))) |
| 1028 | + [:button {:on-click back-to-menu |
| 1029 | + :style {:padding "12px 24px" |
| 1030 | + :background "#4caf50" |
| 1031 | + :color "white" |
| 1032 | + :border "none" |
| 1033 | + :border-radius "6px" |
| 1034 | + :cursor "pointer" |
| 1035 | + :font-weight "600" |
| 1036 | + :font-size "16px" |
| 1037 | + :flex "1"}} |
| 1038 | + "✓ Finish"] |
| 1039 | + [:button {:on-click next-slide |
| 1040 | + :style {:padding "12px 24px" |
| 1041 | + :background "#2196f3" |
| 1042 | + :color "white" |
| 1043 | + :border "none" |
| 1044 | + :border-radius "6px" |
| 1045 | + :cursor "pointer" |
| 1046 | + :font-weight "600" |
| 1047 | + :font-size "16px" |
| 1048 | + :flex "1"}} |
| 1049 | + "Next →"])]]]]))}))) |
1025 | 1050 |
|
1026 | 1051 | ;; ============================================================================ |
1027 | 1052 | ;; Main Component |
|
0 commit comments