diff options
| -rw-r--r-- | main.go | 11 | ||||
| -rw-r--r-- | public/gallery.js | 26 | ||||
| -rw-r--r-- | public/style.css | 1 | 
3 files changed, 30 insertions, 8 deletions
@@ -813,10 +813,14 @@ func handleAPIInfo(w http.ResponseWriter, r *http.Request) {  	var err error  	result.Width, result.Height, err = getImageDimensions(params.SHA1) -	if err != nil { +	if errors.Is(err, sql.ErrNoRows) { +		http.Error(w, err.Error(), http.StatusNotFound) +		return +	} else if err != nil {  		http.Error(w, err.Error(), http.StatusInternalServerError)  		return  	} +  	result.Paths, err = getImagePaths(params.SHA1)  	if err != nil {  		http.Error(w, err.Error(), http.StatusInternalServerError) @@ -920,7 +924,10 @@ func handleAPISimilar(w http.ResponseWriter, r *http.Request) {  		SELECT width, height, dhash, IFNULL(thumbw, 0), IFNULL(thumbh, 0)  		FROM image WHERE sha1 = ?`, params.SHA1).Scan(&width, &height, &dhash,  		&result.Info.ThumbW, &result.Info.ThumbH) -	if err != nil { +	if errors.Is(err, sql.ErrNoRows) { +		http.Error(w, err.Error(), http.StatusNotFound) +		return +	} else if err != nil {  		http.Error(w, err.Error(), http.StatusInternalServerError)  		return  	} diff --git a/public/gallery.js b/public/gallery.js index 299d372..9d3b067 100644 --- a/public/gallery.js +++ b/public/gallery.js @@ -1,14 +1,25 @@  'use strict' +let callActive = false +let callFaulty = false +  function call(method, params) { -	// TODO: Make it apparent when results result in errors: -	//  - With responseType == "json", m.request() always expects JSON, -	//    and error.message is null if it fails, but we can handle it manually. -	//  - Go can wrap all errors into trivial strings before writing. +	// XXX: At least with POST, unsuccessful requests result +	// in catched errors containing Errors with a null message. +	// This is an issue within XMLHttpRequest. +	callActive++  	return m.request({  		method: "POST",  		url: `/api/${method}`,  		body: params, +	}).then(result => { +		callActive-- +		callFaulty = false +		return result +	}).catch(error => { +		callActive-- +		callFaulty = true +		throw error  	})  } @@ -72,8 +83,11 @@ let Header = {  		return m('.header', {}, [  			m('nav', main),  			m('nav', context), -			// TODO: End it with an activity indicator. -			m('.activity', '☺'), +			callFaulty +				? m('.activity.error[title=Error]', '●') +				: callActive +					? m('.activity[title=Busy]', '●') +					: m('.activity[title=Idle]', '○'),  		])  	},  } diff --git a/public/style.css b/public/style.css index e0fc004..1bdeb3f 100644 --- a/public/style.css +++ b/public/style.css @@ -22,6 +22,7 @@ a { color: inherit; }  	background: #fff linear-gradient(#eee, #fff); }  .header nav a.active, .header nav a:hover { padding-bottom: .4rem; }  .header .activity { padding: .25rem .5rem; align-self: center; color: #fff; } +.header .activity.error { color: #f00; }  .sidebar { padding: .25rem .5rem; background: var(--shade-color);  	border-right: 1px solid #ccc; overflow: auto;  | 
