Completion
|
@ -53,6 +53,7 @@
|
|||
(meta ((name "viewport") (content "width=device-width, initial-scale=1")))
|
||||
(title ,title)
|
||||
(link ((rel "stylesheet") (href "/bootstrap/css/bootstrap.min.css") (type "text/css")))
|
||||
(link ((rel "stylesheet") (href "/jquery-ui.min.css") (type "text/css")))
|
||||
(link ((rel "stylesheet") (href "/style.css") (type "text/css")))
|
||||
,@(for/list ((sheet (bootstrap-page-stylesheets)))
|
||||
`(link ((rel "stylesheet") (href ,sheet) (type "text/css")))))
|
||||
|
@ -78,6 +79,7 @@
|
|||
|
||||
(script ((type "text/javascript") (src "/jquery.min.js")))
|
||||
(script ((type "text/javascript") (src "/jquery.tablesorter.min.js")))
|
||||
(script ((type "text/javascript") (src "/jquery-ui.min.js")))
|
||||
(script ((type "text/javascript") (src "/bootstrap/js/bootstrap.min.js")))
|
||||
(script ((type "text/javascript") (src "/site.js")))
|
||||
,@(for/list ((script (bootstrap-page-scripts)))
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
(string-trim email)))))
|
||||
|
||||
(define (gravatar-image-url email [size 80] #:extension [extension ""] #:default [default "identicon"])
|
||||
(format "http://www.gravatar.com/avatar/~a~a?s=~a&d=~a"
|
||||
(format "https://www.gravatar.com/avatar/~a~a?s=~a&d=~a"
|
||||
(gravatar-hash email)
|
||||
extension
|
||||
size
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
(require (only-in web-server/private/util exn->string))
|
||||
|
||||
(define reload-poll-interval 0.5) ;; seconds
|
||||
(define reload-failure-retry-delay (make-parameter 10)) ;; seconds
|
||||
(define reload-failure-retry-delay (make-parameter 5)) ;; seconds
|
||||
|
||||
(struct entry-point (name module-path identifier-symbol [value #:mutable]) #:prefab)
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
(hash-remove! (sessions) session-key))
|
||||
|
||||
(define (lookup-session/touch! session-key)
|
||||
(log-info "Looking up session ~a" session-key)
|
||||
(define s (hash-ref (sessions) session-key (lambda () #f)))
|
||||
(and s
|
||||
(let ((s1 (struct-copy session s [expiry (+ (current-inexact-milliseconds)
|
||||
|
|
20
src/site.rkt
|
@ -10,6 +10,7 @@
|
|||
(require racket/string)
|
||||
(require net/uri-codec)
|
||||
(require web-server/servlet)
|
||||
(require json)
|
||||
(require "gravatar.rkt")
|
||||
(require "bootstrap.rkt")
|
||||
(require "html-utils.rkt")
|
||||
|
@ -51,6 +52,8 @@
|
|||
[("package" (string-arg) "edit") edit-package-page]
|
||||
[("create") edit-package-page]
|
||||
[("logout") logout-page]
|
||||
[("json" "search-completions") json-search-completions]
|
||||
[("json" "all-tags") json-all-tags]
|
||||
))
|
||||
|
||||
(define (on-continuation-expiry request)
|
||||
|
@ -457,7 +460,7 @@
|
|||
|
||||
(define (main-page request)
|
||||
(parameterize ((bootstrap-active-navigation nav-index)
|
||||
(bootstrap-page-scripts '("/mainpage.js")))
|
||||
(bootstrap-page-scripts '("/searchbox.js")))
|
||||
(define package-name-list (package-search "" '((main-distribution #f))))
|
||||
(authentication-wrap
|
||||
#:request request
|
||||
|
@ -1057,7 +1060,7 @@
|
|||
|
||||
(define (search-page request)
|
||||
(parameterize ((bootstrap-active-navigation nav-search)
|
||||
(bootstrap-page-scripts '("/searchpage.js")))
|
||||
(bootstrap-page-scripts '("/searchbox.js")))
|
||||
(authentication-wrap
|
||||
#:request request
|
||||
(define-form-bindings request ([search-text q ""]
|
||||
|
@ -1086,3 +1089,16 @@
|
|||
(p ((class "package-count"))
|
||||
,(format "~a packages found" (length package-name-list)))
|
||||
,(package-summary-table package-name-list))))))))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (json-search-completions request)
|
||||
(define completions (set-union (list->set (map ~a (all-package-names))) (all-tags)))
|
||||
(response/output #:mime-type #"application/json"
|
||||
(lambda (response-port)
|
||||
(write-json (set->list completions) response-port))))
|
||||
|
||||
(define (json-all-tags request)
|
||||
(response/output #:mime-type #"application/json"
|
||||
(lambda (response-port)
|
||||
(write-json (set->list (all-tags)) response-port))))
|
||||
|
|
BIN
static/images/ui-bg_diagonals-thick_18_b81900_40x40.png
Normal file
After Width: | Height: | Size: 457 B |
BIN
static/images/ui-bg_diagonals-thick_20_666666_40x40.png
Normal file
After Width: | Height: | Size: 351 B |
BIN
static/images/ui-bg_flat_10_000000_40x100.png
Normal file
After Width: | Height: | Size: 244 B |
BIN
static/images/ui-bg_glass_100_f6f6f6_1x400.png
Normal file
After Width: | Height: | Size: 301 B |
BIN
static/images/ui-bg_glass_100_fdf5ce_1x400.png
Normal file
After Width: | Height: | Size: 387 B |
BIN
static/images/ui-bg_glass_65_ffffff_1x400.png
Normal file
After Width: | Height: | Size: 246 B |
BIN
static/images/ui-bg_gloss-wave_35_f6a828_500x100.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
static/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
Normal file
After Width: | Height: | Size: 317 B |
BIN
static/images/ui-bg_highlight-soft_75_ffe45c_1x100.png
Normal file
After Width: | Height: | Size: 367 B |
BIN
static/images/ui-icons_222222_256x240.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
static/images/ui-icons_228ef1_256x240.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
static/images/ui-icons_ef8c08_256x240.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
static/images/ui-icons_ffd27a_256x240.png
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
static/images/ui-icons_ffffff_256x240.png
Normal file
After Width: | Height: | Size: 6.3 KiB |
7
static/jquery-ui.min.css
vendored
Normal file
13
static/jquery-ui.min.js
vendored
Normal file
5
static/jquery-ui.structure.min.css
vendored
Normal file
5
static/jquery-ui.theme.min.css
vendored
Normal file
|
@ -1,3 +0,0 @@
|
|||
$(document).ready(function () {
|
||||
$("#q").focus();
|
||||
});
|
7
static/searchbox.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
$(document).ready(function () {
|
||||
$("#q").focus();
|
||||
$.getJSON("/json/search-completions", function (searchCompletions) {
|
||||
searchCompletions.sort();
|
||||
PkgSite.multiTermComplete(PkgSite.preventTabMovingDuringSelection($("#q")), searchCompletions);
|
||||
});
|
||||
});
|
|
@ -1,3 +0,0 @@
|
|||
$(document).ready(function () {
|
||||
$("#q").focus();
|
||||
});
|
|
@ -1,3 +1,43 @@
|
|||
PkgSite = (function () {
|
||||
function preventTabMovingDuringSelection(x) {
|
||||
return x.bind("keydown", function (e) {
|
||||
if (e.which === $.ui.keyCode.TAB && $(this).autocomplete("instance").menu.active) {
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function multiTermComplete(x, completions) {
|
||||
return x.autocomplete({
|
||||
source: function (req, resp) {
|
||||
resp($.ui.autocomplete.filter(completions, req.term.split(/\s+/).pop()));
|
||||
},
|
||||
focus: function () {
|
||||
return false;
|
||||
},
|
||||
select: function (event, ui) {
|
||||
var terms = this.value.split(/\s+/);
|
||||
terms.pop();
|
||||
terms.push(ui.item.value);
|
||||
this.value = terms.join(" ") + " ";
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
multiTermComplete: multiTermComplete,
|
||||
preventTabMovingDuringSelection: preventTabMovingDuringSelection
|
||||
};
|
||||
})();
|
||||
|
||||
$(document).ready(function () {
|
||||
$("table.sortable").tablesorter();
|
||||
|
||||
if ($("#tags").length) {
|
||||
$.getJSON("/json/all-tags", function (allTags) {
|
||||
allTags.sort();
|
||||
PkgSite.multiTermComplete(PkgSite.preventTabMovingDuringSelection($("#tags")), allTags);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|