aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Ángel Moreno <mail@migalmoreno.com>2022-11-21 17:40:02 +0100
committerMiguel Ángel Moreno <mail@migalmoreno.com>2022-11-21 17:40:20 +0100
commitba1dc8f1d7433869a7586c4a21f622fea6857d1d (patch)
tree38c23430d9c97594d65ca830761cb4c4a8a3e373
Initial commit.
-rw-r--r--LICENSE29
-rw-r--r--mosaic.lisp149
-rw-r--r--nx-mosaic.asd9
-rw-r--r--package.lisp19
4 files changed, 206 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7b9e724
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2022, conses <contact@conses.eu>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/mosaic.lisp b/mosaic.lisp
new file mode 100644
index 0000000..5c31591
--- /dev/null
+++ b/mosaic.lisp
@@ -0,0 +1,149 @@
+;; TODO: Add bookmark widget
+;; TODO: Add weather widget
+(in-package #:nx-mosaic)
+(nyxt:use-nyxt-package-nicknames)
+
+(define-class font-settings ()
+ ((font-size
+ 14
+ :type number
+ :documentation "The font size to use."))
+ (:export-class-name-p t)
+ (:export-accessor-names-p t)
+ (:export-slot-names-p t)
+ (:accessor-name-transformer (class*:make-name-transformer name))
+ (:documentation "The font settings to use throughout widgets.")
+ (:metaclass user-class))
+
+(define-class widget ()
+ ((font-settings
+ (make-instance 'font-settings)
+ :type font-settings
+ :documentation "The font settings for the widget.")
+ (visible-p
+ t
+ :type boolean
+ :documentation "Whether the widget should be shown."))
+ (:export-class-name-p t)
+ (:export-accessor-names-p t)
+ (:export-slot-names-p t)
+ (:accessor-name-transformer (class*:make-name-transformer name))
+ (:documentation "An individual widget.")
+ (:metaclass user-class))
+
+(defgeneric display-widget (widget buffer)
+ (:documentation "Display the markup of WIDGET in BUFFER."))
+
+(define-class time-widget (widget)
+ ((timezone
+ nil
+ :type (or null string)
+ :documentation "The timezone to display time for.")
+ (font-settings
+ (make-instance 'font-settings
+ :font-size 80)))
+ (:export-class-name-p t)
+ (:export-accessor-names-p t)
+ (:export-slot-names-p t)
+ (:accessor-name-transformer (class*:make-name-transformer name))
+ (:documentation "A time widget."))
+
+(defmethod display-widget ((widget time-widget) buffer)
+ (let ((time-style
+ (theme:themed-css (theme *browser*)
+ ("#time"
+ :font-size (font-size (font-settings widget))))))
+ (hooks:once-on (nyxt:buffer-loaded-hook buffer) (buffer)
+ (ps-eval
+ :buffer buffer
+ (defun set-time ()
+ (let ((time (ps:new (-Date))))
+ (setf (ps:@ (nyxt/ps:qs document "#time") |innerHTML|)
+ (ps:chain time
+ (|toLocaleString|
+ (array)
+ (ps:create hour "2-digit"
+ minute "2-digit"
+ hour12 nil))))))
+ (set-time)
+ (ps:chain window (|setInterval| |setTime| 1000))))
+ (spinneret:with-html-string
+ (:style time-style)
+ (:div :id "widget-container"
+ (:h1 :id "time")))))
+
+(define-class greeting-widget (widget)
+ ((name
+ nil
+ :type (or null string)
+ :documentation "The name to show in the greeting.")
+ (font-settings
+ (make-instance 'font-settings
+ :font-size 40)))
+ (:export-class-name-p t)
+ (:export-accessor-names-p t)
+ (:export-slot-names-p t)
+ (:accessor-name-transformer (class*:make-name-transformer name))
+ (:documentation "A greeting widget."))
+
+(defmethod display-widget ((widget greeting-widget) buffer)
+ (let ((greeting-style (theme:themed-css (theme *browser*)
+ ("#greeting"
+ :font-size (font-size (font-settings widget))))))
+ (hooks:once-on (nyxt:buffer-loaded-hook buffer) (buffer)
+ (ps-eval
+ :buffer buffer
+ (defun set-greeting ()
+ (let* ((time (ps:new (-Date)))
+ (hour (ps:chain time (|getHours|)))
+ (greetings-mapping
+ (ps:loop :for i :from 0 :to 24
+ :collect (cond
+ ((< i 3) "Sleep well")
+ ((and (> i 2) (< i 6)) "Rise and shine")
+ ((and (> i 5) (< i 10)) "Good morning")
+ ((and (> i 9) (< i 14)) "Hello")
+ ((and (> i 13) (< i 18)) "Good afternoon")
+ ((and (> i 17) (< i 22)) "Good evening")
+ (t "Good night")))))
+ (setf (ps:@ (nyxt/ps:qs document "#message") |innerHTML|)
+ (elt greetings-mapping hour))))
+ (set-greeting)
+ (ps:chain window (|setInterval| |setGreeting| 60000))))
+ (spinneret:with-html-string
+ (:style greeting-style)
+ (:div
+ (:h1 :id "greeting"
+ (:p :id "message")
+ (:p :id "name"
+ (str:concat (when (name widget)
+ (str:concat " ," (name widget))))))))))
+
+(defparameter *widgets*
+ (list
+ (make-instance 'time-widget)
+ (make-instance 'greeting-widget))
+ "The list of widgets")
+
+(nyxt::define-internal-page-command-global mosaic ()
+ (buffer "*Mosaic*" 'nyxt:base-mode)
+ "Open a `nx-mosaic' page."
+ (let ((mosaic-style (theme:themed-css (theme *browser*)
+ (body
+ :padding 0
+ :margin 0
+ :background theme:background
+ :color theme:on-background)
+ ("#mosaic-container"
+ :height "100vh"
+ :display "flex"
+ :align-items "center"
+ :text-align "center"
+ :flex-wrap "wrap"
+ :justify-content "center"))))
+ (spinneret:with-html-string
+ (:style mosaic-style)
+ (:div :id "mosaic-container"
+ (:div :class "widgets-container"
+ (loop for widget in *widgets*
+ collect (:raw (display-widget widget buffer))))))))
diff --git a/nx-mosaic.asd b/nx-mosaic.asd
new file mode 100644
index 0000000..98bdecd
--- /dev/null
+++ b/nx-mosaic.asd
@@ -0,0 +1,9 @@
+(defsystem #:nx-mosaic
+ :description "nx-mosaic is an extensible and configurable new-buffer page for Nyxt."
+ :author "conses"
+ :license "BSD 3-Clause"
+ :version "0.0.1"
+ :serial t
+ :depends-on (#:nyxt)
+ :components ((:file "package")
+ (:file "mosaic")))
diff --git a/package.lisp b/package.lisp
new file mode 100644
index 0000000..099924a
--- /dev/null
+++ b/package.lisp
@@ -0,0 +1,19 @@
+(uiop:define-package #:nx-mosaic
+ (:nicknames #:mosaic)
+ (:use #:cl)
+ (:import-from #:nyxt
+ #:define-class
+ #:user-class
+ #:define-mode
+ #:define-command-global
+ #:define-internal-page-command-global
+ #:current-buffer
+ #:url
+ #:buffer
+ #:*browser*
+ #:theme
+ #:ps-eval)
+ (:import-from #:serapeum
+ #:->
+ #:export-always)
+ (:documentation "nx-mosaic is an extensible and configurable Nyxt new-buffer page."))