implement server-side alert closing
Rather than using bootstrap's client-side closing. Now closed alerts stay closed.
This commit is contained in:
parent
1f671ee40c
commit
a994130843
5 changed files with 30 additions and 103 deletions
|
@ -37,7 +37,15 @@ data Alert = Alert
|
|||
}
|
||||
|
||||
{- Higher AlertId indicates a more recent alert. -}
|
||||
type AlertId = Integer
|
||||
newtype AlertId = AlertId Integer
|
||||
deriving (Read, Show, Eq, Ord)
|
||||
|
||||
{- Note: This first alert id is used for yesod's message. -}
|
||||
firstAlertId :: AlertId
|
||||
firstAlertId = AlertId 0
|
||||
|
||||
nextAlertId :: AlertId -> AlertId
|
||||
nextAlertId (AlertId i) = AlertId $ succ i
|
||||
|
||||
type AlertPair = (AlertId, Alert)
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ newDaemonStatus = DaemonStatus
|
|||
<*> pure Nothing
|
||||
<*> pure M.empty
|
||||
<*> pure M.empty
|
||||
<*> pure 0
|
||||
<*> pure firstAlertId
|
||||
<*> pure []
|
||||
<*> newNotificationBroadcaster
|
||||
<*> newNotificationBroadcaster
|
||||
|
@ -217,7 +217,7 @@ addAlert dstatus alert = notifyAlert dstatus `after` modifyDaemonStatus dstatus
|
|||
where
|
||||
go s = (s { alertMax = i, alertMap = m }, i)
|
||||
where
|
||||
i = alertMax s + 1
|
||||
i = nextAlertId $ alertMax s
|
||||
m = M.insertWith' const i alert (alertMap s)
|
||||
|
||||
removeAlert :: DaemonStatusHandle -> AlertId -> IO ()
|
||||
|
|
|
@ -93,6 +93,7 @@ mkYesod "WebApp" [parseRoutes|
|
|||
/noscriptauto NoScriptAutoR GET
|
||||
/transfers/#NotificationId TransfersR GET
|
||||
/sidebar/#NotificationId SideBarR GET
|
||||
/closealert/#AlertId CloseAlert GET
|
||||
/config ConfigR GET
|
||||
/addrepository AddRepositoryR GET
|
||||
/static StaticR Static getStatic
|
||||
|
@ -102,6 +103,10 @@ instance PathPiece NotificationId where
|
|||
toPathPiece = pack . show
|
||||
fromPathPiece = readish . unpack
|
||||
|
||||
instance PathPiece AlertId where
|
||||
toPathPiece = pack . show
|
||||
fromPathPiece = readish . unpack
|
||||
|
||||
instance Yesod WebApp where
|
||||
defaultLayout content = do
|
||||
webapp <- getYesod
|
||||
|
@ -110,7 +115,6 @@ instance Yesod WebApp where
|
|||
addStylesheet $ StaticR css_bootstrap_responsive_css
|
||||
addScript $ StaticR jquery_full_js
|
||||
addScript $ StaticR js_bootstrap_dropdown_js
|
||||
addScript $ StaticR js_bootstrap_alert_js
|
||||
$(widgetFile "page")
|
||||
hamletToRepHtml $(hamletFile $ hamletTemplate "bootstrap")
|
||||
|
||||
|
@ -229,7 +233,7 @@ sideBarDisplay noScript = do
|
|||
bootstrapclass Message = "alert-info"
|
||||
|
||||
renderalert (alertid, alert) = addalert
|
||||
(show alertid)
|
||||
alertid
|
||||
(alertClosable alert)
|
||||
(alertBlockDisplay alert)
|
||||
(bootstrapclass $ alertClass alert)
|
||||
|
@ -238,11 +242,14 @@ sideBarDisplay noScript = do
|
|||
StringAlert s -> [whamlet|#{s}|]
|
||||
WidgetAlert w -> w alert
|
||||
|
||||
rendermessage msg = addalert "yesodmessage" True False
|
||||
rendermessage msg = addalert firstAlertId True False
|
||||
"alert-info" Nothing [whamlet|#{msg}|]
|
||||
|
||||
addalert :: String -> Bool -> Bool -> Text -> Maybe String -> Widget -> Widget
|
||||
addalert alertid closable block divclass heading widget = $(widgetFile "alert")
|
||||
addalert :: AlertId -> Bool -> Bool -> Text -> Maybe String -> Widget -> Widget
|
||||
addalert i closable block divclass heading widget = do
|
||||
let alertid = show i
|
||||
let closealert = CloseAlert i
|
||||
$(widgetFile "alert")
|
||||
|
||||
{- Called by client to get a sidebar display.
|
||||
-
|
||||
|
@ -259,6 +266,12 @@ getSideBarR nid = do
|
|||
page <- widgetToPageContent $ sideBarDisplay True
|
||||
hamletToRepHtml $ [hamlet|^{pageBody page}|]
|
||||
|
||||
{- Called by the client to close an alert. -}
|
||||
getCloseAlert :: AlertId -> Handler ()
|
||||
getCloseAlert i = do
|
||||
webapp <- getYesod
|
||||
void $ liftIO $ removeAlert (daemonStatus webapp) i
|
||||
|
||||
dashboard :: Bool -> Bool -> Widget
|
||||
dashboard noScript warnNoScript = do
|
||||
sideBarDisplay noScript
|
||||
|
|
94
static/js/bootstrap-alert.js
vendored
94
static/js/bootstrap-alert.js
vendored
|
@ -1,94 +0,0 @@
|
|||
/* ==========================================================
|
||||
* bootstrap-alert.js v2.0.2
|
||||
* http://twitter.github.com/bootstrap/javascript.html#alerts
|
||||
* ==========================================================
|
||||
* Copyright 2012 Twitter, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ========================================================== */
|
||||
|
||||
|
||||
!function( $ ){
|
||||
|
||||
"use strict"
|
||||
|
||||
/* ALERT CLASS DEFINITION
|
||||
* ====================== */
|
||||
|
||||
var dismiss = '[data-dismiss="alert"]'
|
||||
, Alert = function ( el ) {
|
||||
$(el).on('click', dismiss, this.close)
|
||||
}
|
||||
|
||||
Alert.prototype = {
|
||||
|
||||
constructor: Alert
|
||||
|
||||
, close: function ( e ) {
|
||||
var $this = $(this)
|
||||
, selector = $this.attr('data-target')
|
||||
, $parent
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
|
||||
}
|
||||
|
||||
$parent = $(selector)
|
||||
$parent.trigger('close')
|
||||
|
||||
e && e.preventDefault()
|
||||
|
||||
$parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
|
||||
|
||||
$parent
|
||||
.trigger('close')
|
||||
.removeClass('in')
|
||||
|
||||
function removeElement() {
|
||||
$parent
|
||||
.trigger('closed')
|
||||
.remove()
|
||||
}
|
||||
|
||||
$.support.transition && $parent.hasClass('fade') ?
|
||||
$parent.on($.support.transition.end, removeElement) :
|
||||
removeElement()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ALERT PLUGIN DEFINITION
|
||||
* ======================= */
|
||||
|
||||
$.fn.alert = function ( option ) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
, data = $this.data('alert')
|
||||
if (!data) $this.data('alert', (data = new Alert(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
$.fn.alert.Constructor = Alert
|
||||
|
||||
|
||||
/* ALERT DATA-API
|
||||
* ============== */
|
||||
|
||||
$(function () {
|
||||
$('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
|
||||
})
|
||||
|
||||
}( window.jQuery );
|
|
@ -1,4 +1,4 @@
|
|||
<div .alert .fade .in .#{divclass} :block:.alert-block ##{alertid}>
|
||||
<div .alert .fade .in .#{divclass} :block:.alert-block ##{alertid} :closable:onclick="(function( $ ) { $.get('@{closealert}') })( jQuery );">
|
||||
$if closable
|
||||
<a .close data-dismiss="alert" href="#">×</a>
|
||||
$maybe h <- heading
|
||||
|
|
Loading…
Reference in a new issue