liquid_feedback_frontend
changeset 211:4993b71b383f
First checkin of lf2 (frontend second generation) prototype
line diff
1.1 --- a/app/main/_filter_view/34_stylesheet.lua Sat Feb 05 20:01:09 2011 +0100 1.2 +++ b/app/main/_filter_view/34_stylesheet.lua Wed Mar 02 20:06:26 2011 +0100 1.3 @@ -41,7 +41,7 @@ 1.4 slot.set_layout("blank") 1.5 end 1.6 1.7 -if request.get_module() ~= "api" and request.get_view() ~= "list_rss" and request.get_module() ~= "sitemap" then 1.8 +if request.get_module() ~= "lf2" and request.get_module() ~= "api" and request.get_view() ~= "list_rss" and request.get_module() ~= "sitemap" then 1.9 ui.container{ 1.10 attr = { 1.11 class = web20 and "web20" or "web10"
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/app/main/_layout/lf2.html Wed Mar 02 20:06:26 2011 +0100 2.3 @@ -0,0 +1,577 @@ 2.4 +<!-- <html> --> 2.5 +<head> 2.6 +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 2.7 +<style> 2.8 + 2.9 +/* CSS reset */ 2.10 + 2.11 +html, body, div, span, applet, object, iframe, 2.12 +h1, h2, h3, h4, h5, h6, p, blockquote, pre, 2.13 +a, abbr, acronym, address, big, cite, code, 2.14 +del, dfn, em, font, img, ins, kbd, q, s, samp, 2.15 +small, strike, strong, sub, sup, tt, var, 2.16 +dl, dt, dd, ol, ul, li, 2.17 +fieldset, form, label, legend, 2.18 +table, caption, tbody, tfoot, thead, tr, th, td { 2.19 + margin: 0; 2.20 + padding: 0; 2.21 + border: 0; 2.22 + outline: 0; 2.23 + font-weight: inherit; 2.24 + font-style: inherit; 2.25 + font-size: 100%; 2.26 + font-family: inherit; 2.27 + vertical-align: baseline; 2.28 +} 2.29 +/* remember to define focus styles! */ 2.30 +:focus { 2.31 + outline: 0; 2.32 +} 2.33 +body { 2.34 + line-height: 1; 2.35 + color: black; 2.36 + background: white; 2.37 +} 2.38 +ol, ul { 2.39 + list-style: none; 2.40 +} 2.41 +/* tables still need 'cellspacing="0"' in the markup */ 2.42 +table { 2.43 + border-collapse: separate; 2.44 + border-spacing: 0; 2.45 +} 2.46 +caption, th, td { 2.47 + text-align: left; 2.48 + font-weight: normal; 2.49 +} 2.50 +blockquote:before, blockquote:after, 2.51 +q:before, q:after { 2.52 + content: ""; 2.53 +} 2.54 +blockquote, q { 2.55 + quotes: "" ""; 2.56 +} 2.57 + 2.58 +/* end CSS reset */ 2.59 + 2.60 + 2.61 +/* 2.62 + Global settings 2.63 +*/ 2.64 +body { 2.65 + font-family: sans-serif; 2.66 + background-color: #7df; 2.67 + color: #000; 2.68 +} 2.69 + 2.70 +a { 2.71 + background-color: #ffffff; 2.72 + color: #000; 2.73 +} 2.74 + 2.75 +/* 2.76 + Main top navigation 2.77 +*/ 2.78 + 2.79 +.tab1 { 2.80 + background-color: #444; 2.81 + color: #000; 2.82 +} 2.83 + 2.84 +.tab1 .right { 2.85 + float: right; 2.86 +} 2.87 + 2.88 +.tab1 a { 2.89 + float: left; 2.90 + padding: 0.5ex 0.5em 0.5ex 0.5em; 2.91 + margin-left: 0.5em; 2.92 + background-color: #444; 2.93 + color: #fff; 2.94 + font-weight: bold; 2.95 +} 2.96 + 2.97 +.tab1 .right a { 2.98 + margin-left: 0; 2.99 + margin-right: 0.5em; 2.100 +} 2.101 + 2.102 +.tab1 a.active { 2.103 + background-color: #7df; 2.104 +} 2.105 + 2.106 +/* 2.107 + Default slot 2.108 +*/ 2.109 + 2.110 +.slot_default { 2.111 + margin: 2ex 1% 2ex 32%; 2.112 + position: relative; 2.113 + width: 67%; 2.114 +} 2.115 + 2.116 +/* 2.117 + Sidebar 2.118 +*/ 2.119 + 2.120 +.slot_sidebar { 2.121 + margin: 2ex 1% 2ex 1%; 2.122 + float: left; 2.123 + width: 30%; 2.124 +} 2.125 + 2.126 +.slot_sidebar .box { 2.127 + width: 100%; 2.128 +} 2.129 + 2.130 + 2.131 +/* 2.132 + Boxes 2.133 +*/ 2.134 + 2.135 +.box a { 2.136 + text-decoration: none; 2.137 + color: #46a; 2.138 +} 2.139 + 2.140 +.boxhead, 2.141 +a.boxhead { 2.142 + /* position */ 2.143 + display: block; 2.144 + margin-bottom: 0.5ex; 2.145 + margin-top: 1ex; 2.146 + margin-left: 0.5em; 2.147 + 2.148 + /* color */ 2.149 + background-color: #7df; 2.150 + color: #000; 2.151 + 2.152 + /* text format */ 2.153 + font-weight: bold; 2.154 + text-shadow: 2px 2px 2px #fff; 2.155 +} 2.156 + 2.157 +.box { 2.158 + /* position */ 2.159 + position: relative; 2.160 + width: 100%; 2.161 + margin-bottom: 2ex; 2.162 + 2.163 + /* border and shadow*/ 2.164 + border-radius: 1ex; 2.165 + -moz-border-radius: 1ex; 2.166 + -webkit-box-shadow: 2px 2px 3px 0px #444; 2.167 + -moz-box-shadow: 2px 2px 3px 0px #444; 2.168 + 2.169 + /* color */ 2.170 + background-color: #fff; 2.171 + color: #000; 2.172 + 2.173 +} 2.174 + 2.175 +.box .row { 2.176 + overflow: auto; 2.177 + /* position */ 2.178 + 2.179 + /* border */ 2.180 + border-top: 1px solid #ccc; 2.181 +} 2.182 + 2.183 +.box .row .col { 2.184 + /* position */ 2.185 + padding: 0.5ex 0.2em 0.5ex 0.2em; 2.186 + 2.187 + /* text format */ 2.188 + line-height: 125%; 2.189 +} 2.190 + 2.191 +.box .row .col.left { 2.192 + float: left; 2.193 +} 2.194 + 2.195 +.box .row .col.right { 2.196 + float: right; 2.197 +} 2.198 + 2.199 +.box .row .col.clearleft { 2.200 + clear: left; 2.201 +} 2.202 + 2.203 +.box .row .col.clearright { 2.204 + clear: right; 2.205 +} 2.206 + 2.207 +.box .row .col.toggle { 2.208 + float: left; 2.209 + /* position */ 2.210 + padding-left: 0.4em; 2.211 +} 2.212 + 2.213 +.box .row .col.toggle:hover { 2.214 + /* color */ 2.215 + background-color: #7cf; 2.216 + 2.217 + /* cursor */ 2.218 + cursor: pointer; 2.219 +} 2.220 + 2.221 +.box .row.first .col.toggle { 2.222 + /* border */ 2.223 + border-radius: 1ex 0 0 0; 2.224 +} 2.225 + 2.226 +.box .row.last .col.toggle { 2.227 + /* border */ 2.228 + border-radius: 0 0 0 1ex; 2.229 +} 2.230 + 2.231 +.box .row.toggled .col.first { 2.232 + /* position */ 2.233 + margin-left: 1.5em; 2.234 +} 2.235 + 2.236 +.box .row.first { 2.237 + /* border */ 2.238 + border-top: none; 2.239 +} 2.240 + 2.241 +.box .row .col.first { 2.242 + /* position */ 2.243 + padding-left: 0.5em; 2.244 +} 2.245 + 2.246 +.box .row.toggled .col.first { 2.247 + /* position */ 2.248 + padding-left: 0.2em; 2.249 +} 2.250 + 2.251 +.box .row .col { 2.252 +xborder: 1px solid red !important; 2.253 +} 2.254 + 2.255 +.box .row.head { 2.256 + background-color: #e4e7f0; 2.257 + color: #000; 2.258 + border-radius: 1ex 1ex 0 0; 2.259 +} 2.260 + 2.261 +.box .row.head .col a { 2.262 + background-color: #e4e7f0; 2.263 + color: #3B6E7F; 2.264 +} 2.265 + 2.266 +.box .row.head2 { 2.267 + background-color: #f2f3f7; 2.268 + color: #000; 2.269 +} 2.270 + 2.271 +.box .row.head2 .col a { 2.272 + background-color: #f2f3f7; 2.273 + color: #3B6E7F; 2.274 +} 2.275 + 2.276 + 2.277 +.box .row .col a { 2.278 + color: #3B6E7F; 2.279 +} 2.280 + 2.281 +/* Sidebar hover button */ 2.282 + 2.283 +.hoverbutton_container { 2.284 + position: relative; 2.285 +} 2.286 + 2.287 + 2.288 +.hoverbutton { 2.289 + /* position */ 2.290 + display: none; 2.291 + position: absolute; 2.292 + top: 0px; 2.293 + left: 0px; 2.294 + height: 100%; 2.295 + width: 100%; 2.296 + 2.297 + /* color */ 2.298 + background-color: #fff; 2.299 + 2.300 + /* text format */ 2.301 + font-weight: bold; 2.302 + 2.303 + /* cursor */ 2.304 + cursor: pointer; 2.305 +} 2.306 + 2.307 +.hoverbutton_container:hover .hoverbutton { 2.308 + /* position */ 2.309 + display: block; 2.310 +} 2.311 + 2.312 +.hoverbutton_container:hover .hoverbutton img { 2.313 + /* text format */ 2.314 + vertical-align: middle; 2.315 +} 2.316 + 2.317 +.hoverbutton_container:hover .hoverbutton.noaction { 2.318 + /* color */ 2.319 + background-color: #ccc; 2.320 + 2.321 + /* cursor */ 2.322 + cursor: default; 2.323 +} 2.324 + 2.325 +.hoverbutton_container:hover .hoverbutton.green { 2.326 + background-color: #cfc; 2.327 +} 2.328 + 2.329 +.hoverbutton_container:hover .hoverbutton.red { 2.330 + background-color: #fcc; 2.331 +} 2.332 + 2.333 +.hoverbutton .content { 2.334 + /* position */ 2.335 + padding: 0.5ex 0.2em 0.5ex 0.5em; 2.336 +} 2.337 + 2.338 +/* Scrolled col */ 2.339 + 2.340 +.box .row .col.scrolled { 2.341 + padding: 0; 2.342 + max-height: 300px; 2.343 + overflow: auto; 2.344 +} 2.345 + 2.346 +.box .row .col.scrolled .head { 2.347 + font-weight: bold; 2.348 + padding: 0.5ex 0.2em 0.5ex 0.5em; 2.349 +} 2.350 + 2.351 +/* 2.352 + Bars 2.353 +*/ 2.354 + 2.355 +.bar { 2.356 + float: right; 2.357 + margin-left: 0.3em; 2.358 +} 2.359 + 2.360 +.bar div { 2.361 + margin-top: 2px; 2.362 + float: left; 2.363 + height: 11px; 2.364 +} 2.365 +.bar .green { 2.366 + background-color: #0a0; 2.367 +} 2.368 + 2.369 +.bar .grey { 2.370 + background-color: #eee; 2.371 +} 2.372 + 2.373 +/* 2.374 + Avatars 2.375 +*/ 2.376 + 2.377 +.avatars { 2.378 + overflow: auto; 2.379 +} 2.380 + 2.381 +.avatars .avatar { 2.382 + float: left; 2.383 + margin-left: 2px; 2.384 + margin-right: 2px; 2.385 +} 2.386 + 2.387 +.avatars.normal .avatar { 2.388 + width: 100px; 2.389 + -webkit-box-shadow: 1px 1px 1px #000; 2.390 + background-color: #eee; 2.391 + border-radius: 1ex; 2.392 + -moz-border-radius: 1ex; 2.393 +} 2.394 + 2.395 +.avatars.small .avatar { 2.396 + border: 2px solid #fff; 2.397 + border-radius: 0.5ex; 2.398 + -moz-border-radius: 0.5ex; 2.399 +} 2.400 + 2.401 +.avatars .arrow { 2.402 + float: left; 2.403 + margin-top: 0.3ex; 2.404 +} 2.405 + 2.406 +.avatars .avatar.myweight { 2.407 + border-color: #f70; 2.408 + background-color: #f70; 2.409 +} 2.410 + 2.411 +.avatars .avatar.autoreject { 2.412 + border-color: #f00; 2.413 + background-color: #f00; 2.414 +} 2.415 + 2.416 +.avatars.small .avatar img { 2.417 + border-radius: 0.25ex; 2.418 + -moz-border-radius: 0.25ex; 2.419 +} 2.420 + 2.421 +.avatars.normal .avatar img { 2.422 + margin-left: 0.3em; 2.423 + margin-top: 0.3ex; 2.424 + border-radius: 1ex; 2.425 + -moz-border-radius: 1ex; 2.426 +} 2.427 + 2.428 +.avatars.small .avatar img { 2.429 + height: 24px; 2.430 + width: 24px; 2.431 +} 2.432 + 2.433 +.avatars.normal .avatar img { 2.434 + height: 48px; 2.435 + width: 48px; 2.436 +} 2.437 + 2.438 +.avatars.normal .avatar .name { 2.439 + margin-left: 0.3em; 2.440 + margin-top: 0.3ex; 2.441 + line-height: 100%; 2.442 + font-size: 70%; 2.443 + overflow: hidden; 2.444 + height: 4ex; 2.445 +} 2.446 + 2.447 +.avatars .avatar .weight { 2.448 + text-align: center; 2.449 + font-size: 70%; 2.450 +} 2.451 + 2.452 +.avatars.small .avatar.participation { 2.453 + border-color: #f70; 2.454 +} 2.455 + 2.456 +.avatars.small .avatar.overridden, 2.457 +.avatars.small .arrow.overridden { 2.458 + opacity: 0.3; 2.459 +} 2.460 + 2.461 +/* 2.462 + Area 2.463 +*/ 2.464 + 2.465 +.area .name { 2.466 + color: #444; 2.467 + font-weight: bold; 2.468 +} 2.469 + 2.470 +.area .name a { 2.471 + font-weight: normal; 2.472 +} 2.473 + 2.474 +.area .name .avatars { 2.475 + float: right; 2.476 + margin-top: -3px; 2.477 +} 2.478 + 2.479 +/* Issues */ 2.480 + 2.481 +.issue .issue_id { 2.482 + font-weight: bold; 2.483 +} 2.484 + 2.485 +.issue .state_name { 2.486 + font-style: italic; 2.487 +} 2.488 + 2.489 +.issue .time_left { 2.490 + font-style: italic; 2.491 +} 2.492 + 2.493 +/* Initiatives */ 2.494 + 2.495 +.initiative .name, 2.496 +.initiative a.name { 2.497 + font-weight: bold; 2.498 +} 2.499 + 2.500 +.initiative .authors { 2.501 + /* color */ 2.502 + color: #777; 2.503 + 2.504 + /* text format */ 2.505 + font-size: 80%; 2.506 + font-style: italic; 2.507 +} 2.508 + 2.509 +.initiative .authors a { 2.510 + /* color */ 2.511 +} 2.512 + 2.513 +.drafts .draft .created { 2.514 + font-weight: bold; 2.515 +} 2.516 + 2.517 +.drafts .draft .author_name { 2.518 + font-style: italic; 2.519 +} 2.520 + 2.521 +/* Draft */ 2.522 + 2.523 +.draft { 2.524 + line-height: 135%; 2.525 +} 2.526 + 2.527 +.draft h2 { 2.528 + font-size: 135%; 2.529 + font-weight: bold; 2.530 + margin-bottom: 0.5ex; 2.531 +} 2.532 + 2.533 +.draft h3 { 2.534 + font-size: 135%; 2.535 + margin-bottom: 0.5ex; 2.536 +} 2.537 + 2.538 +.draft p { 2.539 + margin-bottom: 1ex; 2.540 +} 2.541 + 2.542 +.draft ul { 2.543 + padding-left: 2em; 2.544 + list-style: disc; 2.545 +} 2.546 + 2.547 +.draft ul li { 2.548 + margin-bottom: 1ex; 2.549 +} 2.550 + 2.551 +xdiv { border: 1px dotted #c00 !important; } 2.552 + 2.553 + 2.554 +</style> 2.555 +</head> 2.556 +</body> 2.557 +<div class="tab1"> 2.558 + <!-- WEBMCP SLOT topnav --> 2.559 +<br style="clear: both;" /> 2.560 +</div> 2.561 + 2.562 +<!-- WEBMCP SLOT sidebar --> 2.563 +<!-- WEBMCP SLOT default --> 2.564 + 2.565 + 2.566 + <div class="layout_trace" id="layout_trace" style="xdisplay: none"> 2.567 + <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';">TRACE</div> 2.568 + <div id="trace_content" style="display: none;"> 2.569 + <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt> 2.570 + <div id="trace"> </div><hr /> 2.571 + <!-- WEBMCP SLOT trace --> 2.572 + <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';"> 2.573 + close 2.574 + </div> 2.575 + </div> 2.576 + </div> 2.577 + </div> 2.578 + 2.579 +</body> 2.580 +</html>
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/app/main/lf2/_area.lua Wed Mar 02 20:06:26 2011 +0100 3.3 @@ -0,0 +1,75 @@ 3.4 +local area = param.get("area", "table") 3.5 + 3.6 +local membership = Membership:by_pk(area.id, app.session.member_id) 3.7 + 3.8 +local trustees = Member:new_selector() 3.9 + :add_field("delegation_chain.*") 3.10 + :join("delegation_chain(" .. app.session.member_id .. ", " .. area.id .. ", NULL)", "delegation_chain", "member.id = delegation_chain.member_id") 3.11 + :add_order_by("index") 3.12 + :exec() 3.13 + 3.14 +ui.box{ class = "area", content = function() 3.15 + 3.16 + ui.box_row{ class = "head", content = function() 3.17 + ui.box_col{ class = "left name", content = area.name } 3.18 + ui.box_col{ class = "right", content = _("#{direct_count}+#{delegated_count} Mitglieder", { 3.19 + direct_count = area.direct_member_count, 3.20 + delegated_count = area.member_weight - area.direct_member_count 3.21 + } ) } 3.22 + end } 3.23 + 3.24 + if area.description and #area.description > 0 then 3.25 + ui.box_row{ class = "description", content = function() ui.box_col{ content = area.description } end } 3.26 + end 3.27 + 3.28 + ui.box_row{ class = "member_count", content = function() 3.29 + end } 3.30 + 3.31 + ui.box_row{ content = function() 3.32 + ui.box_col{ class = "left", content = function() 3.33 + execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } } 3.34 + end } 3.35 + ui.box_col{ class = "right", content = function() 3.36 + ui.tag{ content = _"[Change] or [revoke] area delegation [prefix]" } 3.37 + ui.link{ text = _"[Change] or [revoke] area delegation [change]" } 3.38 + ui.tag{ content = _"[Change] or [revoke] area delegation [midpart]" } 3.39 + ui.link{ text = _"[Change] or [revoke] area delegation [revoke]" } 3.40 + ui.tag{ content = _"[Change] or [revoke] area delegation [suffix]" } 3.41 + end } 3.42 + end } 3.43 + 3.44 + ui.box_row{ content = function() 3.45 + ui.box_col{ class = "left", content = function() 3.46 + if membership then 3.47 + ui.image{ static = "lf2/icon_star.png" } 3.48 + slot.put(" ", _"You are member of this area") 3.49 + else 3.50 + ui.link{ 3.51 + module = "membership", action = "update", params = { area_id = area.id }, 3.52 + routing = { default = { 3.53 + mode = "redirect", module = "lf2", view = "area", id = area.id 3.54 + } }, 3.55 + text = _"Become a member of this area" 3.56 + } 3.57 + end 3.58 + end } 3.59 + ui.box_col{ class = "right", content = function() 3.60 + if membership then 3.61 + ui.link{ 3.62 + module = "membership", action = "update", params = { area_id = area.id, delete = true }, 3.63 + routing = { default = { 3.64 + mode = "redirect", module = "lf2", view = "area", id = area.id 3.65 + } }, 3.66 + text = _"Give up membership" 3.67 + } 3.68 + end 3.69 + if not trustees then 3.70 + if membership then 3.71 + slot.put(" · ") 3.72 + end 3.73 + ui.link{ text = _"Delegate area...", module = "lf2", view = "delegation" } 3.74 + end 3.75 + end } 3.76 + end } 3.77 + 3.78 +end } 3.79 \ No newline at end of file
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/app/main/lf2/_areas.lua Wed Mar 02 20:06:26 2011 +0100 4.3 @@ -0,0 +1,29 @@ 4.4 +local areas = param.get("areas_selector", "table"):exec() 4.5 +local head_content = param.get("head_content", "function") 4.6 + 4.7 +ui.box{ class = "areas", row_count = #areas, content = function() 4.8 + if head_content then 4.9 + ui.box_row{ class = "head", content = function() ui.box_col{ content = head_content } end } 4.10 + end 4.11 + 4.12 + for i, area in ipairs(areas) do 4.13 + local delegation = Delegation:by_pk(app.session.member_id, area.id) 4.14 + 4.15 + ui.box_row{ 4.16 + class = "area", 4.17 + toggle_content = function() 4.18 + ui.image{ static = "lf2/icon_search_crossed.png" } 4.19 + end, 4.20 + content = function() 4.21 + ui.box_col{ class = "name", content = function() 4.22 + if delegation then 4.23 + execute.view{ module = "lf2", view = "_avatars", params = { members = { delegation.trustee }, size = "small" } } 4.24 + end 4.25 + ui.link{ module = "lf2", view = "area", id = area.id, text = area.name } 4.26 + end } 4.27 + end 4.28 + } 4.29 + 4.30 + end 4.31 + 4.32 +end } 4.33 \ No newline at end of file
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/app/main/lf2/_avatars.lua Wed Mar 02 20:06:26 2011 +0100 5.3 @@ -0,0 +1,51 @@ 5.4 +local members = param.get("members", "table") 5.5 +local hidefirst = param.get("hidefirst", atom.boolean) 5.6 +local size = param.get("size") or "normal" 5.7 + 5.8 +local first_participation = true 5.9 + 5.10 +ui.container{ attr = { class = "avatars " .. size }, content = function() 5.11 + for i, member in ipairs(members) do 5.12 + local class = "arrow" 5.13 + if member.overridden then 5.14 + class = class .. " overridden" 5.15 + end 5.16 + local image 5.17 + local text 5.18 + if member.scope_in == "global" then 5.19 + image = "lf2/icon_delegation_global.png" 5.20 + text = _"Global delegation" 5.21 + elseif member.scope_in == "area" then 5.22 + image = "lf2/icon_delegation_area.png" 5.23 + text = _"Area delegation" 5.24 + elseif member.scope_in == "issue" then 5.25 + image = "lf2/icon_delegation.png" 5.26 + text = _"Issue delegation" 5.27 + end 5.28 + if param.get("arrows", atom.boolean) and (i > 1 or #members == 1) then 5.29 + ui.image{ attr = { title = text, alt = text, class = class }, static = image } 5.30 + slot.put(member.scope) 5.31 + end 5.32 + if not hidefirst or i > 1 then 5.33 + local class = "avatar" 5.34 + if first_participation and member.participation then 5.35 + class = class .. " participation" 5.36 + first_participation = false 5.37 + end 5.38 + if member.overridden then 5.39 + class = class .. " overridden" 5.40 + end 5.41 + ui.container{ attr = { class = class, title = member.name }, content = function() 5.42 + ui.avatar(member, size) 5.43 + --ui.image{ module = "member_image", view = "show", id = member.id, params = { image_type = "avatar" } } 5.44 + if size == "normal" then 5.45 + ui.container{ attr = { class = "name" }, content = member.name } 5.46 + end 5.47 + if size == "small" and member.weight ~= nil then 5.48 + ui.container{ attr = { class = "weight" }, content = member.weight } 5.49 + end 5.50 + end } 5.51 + end 5.52 + end 5.53 +end } 5.54 +
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/app/main/lf2/_delegation_global.lua Wed Mar 02 20:06:26 2011 +0100 6.3 @@ -0,0 +1,23 @@ 6.4 +local trustees = Member:new_selector() 6.5 + :add_field("delegation_chain.*") 6.6 + :join("delegation_chain(" .. tostring(app.session.member.id) .. ", NULL, NULL)", "delegation_chain", "member.id = delegation_chain.member_id") 6.7 + :add_order_by("index") 6.8 + :exec() 6.9 + 6.10 +ui.box{ content = function() 6.11 + ui.box_row{ class = "head", content = function() 6.12 + ui.box_col{ content = _"Global delegation active" } 6.13 + end } 6.14 + ui.box_row{ content = function() ui.box_col{ content = function() 6.15 + execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } } 6.16 + end } end } 6.17 + ui.box_row{ content = function() ui.box_col{ content = function() 6.18 + ui.tag{ content = _"[Change] or [revoke] global delegation [prefix]" } 6.19 + ui.link{ text = _"[Change] or [revoke] global delegation [change]" } 6.20 + ui.tag{ content = _"[Change] or [revoke] global delegation [midpart]" } 6.21 + ui.link{ text = _"[Change] or [revoke] global delegation [revoke]" } 6.22 + ui.tag{ content = _"[Change] or [revoke] global delegation [suffix]" } 6.23 + 6.24 + end } end } 6.25 +end } 6.26 + 6.27 \ No newline at end of file
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/app/main/lf2/_draft.lua Wed Mar 02 20:06:26 2011 +0100 7.3 @@ -0,0 +1,5 @@ 7.4 +local draft = param.get("draft", "table") 7.5 + 7.6 +ui.container{ attr = { class = "draft" }, content = function() 7.7 + slot.put(format.wiki_text(draft.content, draft.formatting_engine)) 7.8 +end }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/app/main/lf2/_filter_view/10_topnav.lua Wed Mar 02 20:06:26 2011 +0100 8.3 @@ -0,0 +1,44 @@ 8.4 +local state = param.get("state") 8.5 +local order = param.get("order") 8.6 + 8.7 +slot.select("topnav", function() 8.8 + 8.9 + ui.link{ 8.10 + attr = { class = state == "closed" and "active" or nil }, 8.11 + text = _"Closed", module = "lf2", view = "index", params = { state = "closed", order = order } 8.12 + } 8.13 + ui.link{ 8.14 + attr = { class = state == "voting" and "active" or nil }, 8.15 + text = _"Voting", module = "lf2", view = "index", params = { state = "voting", order = order } 8.16 + } 8.17 + ui.link{ 8.18 + attr = { class = state == "frozen" and "active" or nil }, 8.19 + text = _"Frozen", module = "lf2", view = "index", params = { state = "frozen", order = order } 8.20 + } 8.21 + ui.link{ 8.22 + attr = { class = state == "discussion" and "active" or nil }, 8.23 + text = _"Discussion", module = "lf2", view = "index", params = { state = "discussion", order = order } 8.24 + } 8.25 + ui.link{ 8.26 + attr = { class = state == "new" and "active" or nil }, 8.27 + text = _"New", module = "lf2", view = "index", params = { state = "new", order = order } 8.28 + } 8.29 + 8.30 + ui.container{ attr = { class = "right" }, content = function() 8.31 + ui.link{ 8.32 + attr = { class = order == "last_change" and "active" or nil }, 8.33 + text = _"Last change", module = "lf2", view = "index", params = { order = "last_change", state = state } 8.34 + } 8.35 + ui.link{ 8.36 + attr = { class = order == "time_left" and "active" or nil }, 8.37 + text = _"Time left", module = "lf2", view = "index", params = { order = "time_left", state = state } 8.38 + } 8.39 + ui.link{ 8.40 + attr = { class = order == "interest" and "active" or nil }, 8.41 + text = _"Interest", module = "lf2", view = "index", params = { order = "interest", state = state } 8.42 + } 8.43 + end } 8.44 + 8.45 +end) 8.46 + 8.47 +execute.inner() 8.48 \ No newline at end of file
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/app/main/lf2/_initiative.lua Wed Mar 02 20:06:26 2011 +0100 9.3 @@ -0,0 +1,95 @@ 9.4 +local initiative = param.get("initiative", "table") 9.5 + 9.6 +ui.container{ attr = { class = "bar" }, content = function() 9.7 + if initiative.issue.fully_frozen and initiative.issue.closed then 9.8 + if initiative.issue.ranks_available then 9.9 + if initiative.negative_votes and initiative.positive_votes then 9.10 + local max_value = initiative.issue.voter_count 9.11 + ui.bargraph{ 9.12 + max_value = max_value, 9.13 + width = 100, 9.14 + bars = { 9.15 + { color = "#0a0", value = initiative.positive_votes }, 9.16 + { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes }, 9.17 + { color = "#a00", value = initiative.negative_votes }, 9.18 + } 9.19 + } 9.20 + else 9.21 + slot.put(" ") 9.22 + end 9.23 + else 9.24 + slot.put(_"Counting of votes") 9.25 + end 9.26 + elseif initiative.issue.population then 9.27 + local max_value = initiative.issue.population 9.28 + ui.bargraph{ 9.29 + max_value = max_value, 9.30 + width = 100, 9.31 + quorum = max_value * (initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den), 9.32 + quorum_color = "#00F", 9.33 + bars = { 9.34 + { color = "#0a0", value = (initiative.satisfied_supporter_count or 0) }, 9.35 + { color = "#bbb", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) }, 9.36 + { color = "#eee", value = max_value - (initiative.supporter_count or 0) }, 9.37 + } 9.38 + } 9.39 + else 9.40 + slot.put(" ") 9.41 + end 9.42 +end } 9.43 + 9.44 +if initiative.issue.fully_frozen and not initiative.issue.closed then 9.45 + if not initiative.admitted then 9.46 + ui.image{ attr = { title = _"Initiative not admitted" }, static = "lf2/icon_cross.png" } 9.47 + slot.put(" ") 9.48 + end 9.49 +end 9.50 + 9.51 +if initiative.issue.closed then 9.52 + if initiative.issue.accepted then 9.53 + if initiative.admitted then 9.54 + if initiative.agreed then 9.55 + if initiative.rank == 1 then 9.56 + ui.image{ static = "lf2/icon_award_gold.png" } 9.57 + else 9.58 + ui.image{ static = "lf2/icon_award_silver.png" } 9.59 + end 9.60 + slot.put(" ") 9.61 + ui.tag{ content = initiative.rank } 9.62 + else 9.63 + ui.image{ attr = { title = _"Initiative not agreed" }, static = "lf2/icon_cross.png" } 9.64 + end 9.65 + else 9.66 + ui.image{ attr = { title = _"Initiative not admitted" }, static = "lf2/icon_cross.png" } 9.67 + end 9.68 + else 9.69 + ui.image{ attr = { title = _"Issue not accepted" }, static = "lf2/icon_cross.png" } 9.70 + end 9.71 + slot.put(" ") 9.72 +end 9.73 + 9.74 +ui.link{ 9.75 + module = "lf2", view = "initiative", id = initiative.id, 9.76 + params = { tab = "draft" }, attr = { class = "name" }, 9.77 + text = initiative.name 9.78 +} 9.79 + 9.80 +ui.container{ attr = { class = "authors" }, content = function() 9.81 + local members = initiative.initiating_members 9.82 + slot.put(_"by", " ") 9.83 + for i, member in ipairs(members) do 9.84 + if i > 1 and i < #members then 9.85 + slot.put(", ") 9.86 + elseif i > 1 then 9.87 + slot.put(" ", _"and", " ") 9.88 + end 9.89 + ui.link{ 9.90 + module = "lf2", view = "initiative", id = initiative.id, 9.91 + params = { member_id = member.id }, content = function() 9.92 + ui.tag{ content = member.name } 9.93 + end 9.94 + } 9.95 + end 9.96 +end } 9.97 + 9.98 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/app/main/lf2/_initiatives.lua Wed Mar 02 20:06:26 2011 +0100 10.3 @@ -0,0 +1,13 @@ 10.4 +local initiatives = param.get("initiatives", "table") 10.5 + 10.6 +initiatives:load("initiating_members", nil, "initiating_members") 10.7 + 10.8 +ui.box{ content = function() 10.9 + for i, initiative in ipairs(initiatives) do 10.10 + 10.11 + ui.box_row{ class = "initiative", content = function() ui.box_col { content = function() 10.12 + execute.view{ module = "lf2", view = "_initiative", params = { initiative = initiative } } 10.13 + end } end } 10.14 + 10.15 + end 10.16 +end } 10.17 \ No newline at end of file
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/app/main/lf2/_interested.lua Wed Mar 02 20:06:26 2011 +0100 11.3 @@ -0,0 +1,12 @@ 11.4 +local interested_members = param.get("interested_members", "table") 11.5 +ui.box{ content = function() 11.6 + ui.box_row{ class = "head interested", content = function() 11.7 + ui.box_col{ class = "", content = _"Interested members" } 11.8 + end } 11.9 + ui.box_row{ class = "interested", content = function() 11.10 + ui.box_col{ content = _"The interested members are updated after some time." } 11.11 + ui.box_col{ class = "", content = function() 11.12 + execute.view{ module = "lf2", view = "_avatars", params = { members = interested_members } } 11.13 + end } 11.14 + end } 11.15 +end }
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/app/main/lf2/_issue_initiatives.lua Wed Mar 02 20:06:26 2011 +0100 12.3 @@ -0,0 +1,72 @@ 12.4 +local initiatives = param.get("initiatives", "table") 12.5 + 12.6 +for i, initiative in ipairs(initiatives) do 12.7 + 12.8 + local first = "" 12.9 + if i == 1 then first = " first" end 12.10 + 12.11 + ui.box_row{ class = "initiative" .. first, content = function() ui.box_col { content = function() 12.12 + 12.13 + ui.link{ 12.14 + module = "lf2", view = "initiative", id = initiative.id, 12.15 + params = { tab = "draft" }, attr = { class = "name" }, 12.16 + text = initiative.name 12.17 + } 12.18 + 12.19 + ui.container{ attr = { class = "bar" }, content = function() 12.20 + if initiative.issue.fully_frozen and initiative.issue.closed then 12.21 + if initiative.issue.ranks_available then 12.22 + if initiative.negative_votes and initiative.positive_votes then 12.23 + local max_value = initiative.issue.voter_count 12.24 + ui.bargraph{ 12.25 + max_value = max_value, 12.26 + width = 100, 12.27 + bars = { 12.28 + { color = "#0a0", value = initiative.positive_votes }, 12.29 + { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes }, 12.30 + { color = "#a00", value = initiative.negative_votes }, 12.31 + } 12.32 + } 12.33 + else 12.34 + slot.put(" ") 12.35 + end 12.36 + else 12.37 + slot.put(_"Counting of votes") 12.38 + end 12.39 + elseif initiative.issue.population then 12.40 + local max_value = initiative.issue.population 12.41 + ui.bargraph{ 12.42 + max_value = max_value, 12.43 + width = 100, 12.44 + quorum = max_value * (initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den), 12.45 + quorum_color = "#00F", 12.46 + bars = { 12.47 + { color = "#0a0", value = (initiative.satisfied_supporter_count or 0) }, 12.48 + { color = "#bbb", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) }, 12.49 + { color = "#eee", value = max_value - (initiative.supporter_count or 0) }, 12.50 + } 12.51 + } 12.52 + else 12.53 + slot.put(" ") 12.54 + end 12.55 + end } 12.56 + 12.57 + ui.container{ attr = { class = "authors" }, content = function() 12.58 + local members = initiative.initiating_members 12.59 + slot.put(_"by", " ") 12.60 + for i, member in ipairs(members) do 12.61 + if i > 1 and i < #members then 12.62 + slot.put(", ") 12.63 + elseif i > 1 then 12.64 + slot.put(" ", _"and", " ") 12.65 + end 12.66 + ui.link{ 12.67 + module = "lf2", view = "initiative", id = initiative.id, 12.68 + params = { member_id = member.id }, text = member.name 12.69 + } 12.70 + end 12.71 + end } 12.72 + 12.73 + end } end } 12.74 + 12.75 +end 12.76 \ No newline at end of file
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/app/main/lf2/_issues.lua Wed Mar 02 20:06:26 2011 +0100 13.3 @@ -0,0 +1,114 @@ 13.4 +local issues = param.get("issues", "table") 13.5 + 13.6 +for i, issue in ipairs(issues) do 13.7 + local initiatives = issue.initiatives 13.8 + 13.9 + local interested_members = issue.interested_members 13.10 + 13.11 + -- prepare interest of current user 13.12 + local interest = issue.interest 13.13 + 13.14 + -- prepare trustees 13.15 + local trustees = Member:new_selector() 13.16 + :add_field("delegation_chain.*") 13.17 + :join("delegation_chain(" .. tostring(app.session.member.id) .. ", NULL, " .. tostring(issue.id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id") 13.18 + :add_order_by("index") 13.19 + :exec() 13.20 + 13.21 + local global_delegation 13.22 + local area_delegation 13.23 + local issue_delegation 13.24 + 13.25 + for i, delegation in ipairs(issue.outgoing_delegations) do 13.26 + if delegation.scope == "global" then global_delegation = delegation 13.27 + elseif delegation.scope == "area" then area_delegation = delegation 13.28 + elseif delegation.scope == "issue" then issue_delegation = delegation 13.29 + end 13.30 + end 13.31 + 13.32 + local delegation = issue_delegation or area_delegation or global_delegation 13.33 + 13.34 + local delegating_interest = issue.delegating_interest 13.35 + 13.36 + ui.box{ class = "issue", content = function() 13.37 + 13.38 + ui.box_row{ class = "head", content = function() 13.39 + 13.40 + ui.box_col{ class = "issue_id left", content = function() 13.41 + ui.link{ 13.42 + module = "lf2", view = "issue", id = issue.id, 13.43 + content = _("Issue ##{id}", { id = issue.id }) 13.44 + } 13.45 + end } 13.46 + 13.47 + ui.box_col{ class = "unit_name right", content = function() 13.48 + ui.link{ 13.49 + module = "lf2", view = "unit", id = 1, 13.50 + content = "Dummy unit name" 13.51 + } 13.52 + end } 13.53 + ui.box_col{ class = "area_name right clearright", content = function() 13.54 + ui.link{ 13.55 + module = "lf2", view = "area_name", id = issue.area_id, 13.56 + content = issue.area.name 13.57 + } 13.58 + end } 13.59 + ui.box_col{ class = "policy_name left clearleft first", content = function() 13.60 + ui.link{ 13.61 + module = "lf2", view = "policy", id = issue.policy_id, 13.62 + content = issue.policy.name 13.63 + } 13.64 + end } 13.65 + 13.66 + end } 13.67 + 13.68 + ui.box_row{ class = "head2", content = function() 13.69 + 13.70 + ui.box_col{ class = "state_name left", content = function() 13.71 + ui.tag{ content = issue.state_name } 13.72 + slot.put(" · ") 13.73 + ui.tag{ content = issue.closed and _("since #{date}", { date = format.date(issue.closed.date) }) or _("#{time_left} left", { time_left = issue.state_time_left }) } 13.74 + end } 13.75 + end } 13.76 + 13.77 + if interest or delegation then 13.78 + ui.box_row{ class = "head2", content = function() 13.79 + ui.box_col{ class = "interest left", content = function() 13.80 + if interest then 13.81 + ui.image{ static = "lf2/icon_star.png" } 13.82 + if issue.closed then 13.83 + slot.put(" ", _"You were interested in this issue") 13.84 + else 13.85 + slot.put(" ", _"You are interested in this issue") 13.86 + end 13.87 + elseif delegating_interest then 13.88 + ui.image{ static = "lf2/icon_delegated_star.png" } 13.89 + if issue.closed then 13.90 + slot.put(" ", _"You were interested in this issue by delegation") 13.91 + else 13.92 + slot.put(" ", _"You are interested in this issue by delegation") 13.93 + end 13.94 + elseif trustees then 13.95 + slot.put(_"You have delegated this issue") 13.96 + else 13.97 + slot.put(_"You are not interested in this issue") 13.98 + end 13.99 + end } 13.100 + -- TODO if delegation ist falsch 13.101 + if delegation then 13.102 + slot.put(tostring(delegation.id)) 13.103 + ui.box_col{ class = "delegation right", content = function() 13.104 + execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } } 13.105 + end } 13.106 + end 13.107 + end } 13.108 + end 13.109 + 13.110 + for i, initiative in ipairs(issue.initiatives) do 13.111 + ui.box_row{ class = "initiative", content = function() ui.box_col { content = function() 13.112 + execute.view{ module = "lf2", view = "_initiative", params = { initiative = initiative } } 13.113 + end } end } 13.114 + end 13.115 + 13.116 + end } 13.117 +end 13.118 \ No newline at end of file
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/app/main/lf2/_issues_issue.lua Wed Mar 02 20:06:26 2011 +0100 14.3 @@ -0,0 +1,77 @@ 14.4 +local issue = param.get("issue", "table") 14.5 +local hide = param.get("hide", "table") or {} 14.6 + 14.7 +local interest = issue.interest 14.8 + 14.9 +local delegations = issue.delegations 14.10 + 14.11 +local global_delegation 14.12 +local area_delegation 14.13 +local issue_delegation 14.14 + 14.15 +for i, delegation in ipairs(issue.delegations) do 14.16 + if delegation.scope == "global" then global_delegation = delegation 14.17 + elseif delegation.scope == "area" then area_delegation = delegation 14.18 + elseif delegation.scope == "issue" then issue_delegation = delegation 14.19 + end 14.20 +end 14.21 + 14.22 +local delegation = issue_delegation or area_delegation or global_delegation 14.23 + 14.24 +local delegating_interest = issue.delegating_interest 14.25 + 14.26 +ui.box{ class = "issue", content = function() 14.27 + 14.28 + ui.box_row{ class = "issue_id", content = function() ui.box_col{ content = function() 14.29 + ui.link{ 14.30 + module = "lf2", view = "issue", id = issue.id, 14.31 + content = _("Issue ##{id}", { id = issue.id }) 14.32 + } 14.33 + end } end } 14.34 + 14.35 + if not hide.unit then 14.36 + ui.box_row{ class = "unit_name", content = function() ui.box_col{ content = function() 14.37 + ui.link{ 14.38 + module = "lf2", view = "unit", id = 1, 14.39 + content = "DE / Berlin / Friedrichshain-Kreuzberg" 14.40 + } 14.41 + end } end } 14.42 + end 14.43 + 14.44 + if not hide.area then 14.45 + ui.box_row{ class = "area_name", content = function() ui.box_col{ content = function() 14.46 + ui.link{ 14.47 + module = "lf2", view = "area", id = issue.area_id, 14.48 + content = issue.area.name 14.49 + } 14.50 + end } end } 14.51 + end 14.52 + 14.53 + 14.54 + ui.box_row{ class = "interest", content = function() 14.55 + if interest then 14.56 + ui.container{ attr = { title = _"You are interested in this issue" }, content = function() 14.57 + ui.image{ static = "lf2/icon_star.png" } 14.58 + end } 14.59 + elseif delegating_interest then 14.60 + ui.container{ attr = { class = "interest", title = _"You are interested in this issue by delegation" }, content = function() 14.61 + ui.image{ static = "lf2/icon_delegated_star.png" } 14.62 + slot.put(delegating_interest.trustee_member_id) 14.63 + end } 14.64 + else 14.65 + end 14.66 + end } 14.67 + 14.68 + ui.box_row{ class = "delegation", content = function() 14.69 + if delegation then 14.70 + ui.box_col{ content = function() 14.71 + execute.view{ module = "lf2", view = "_avatars", params = { members = { app.session.member, delegation.trustee }, arrows = true, hidefirst = true } } 14.72 + end } 14.73 + else 14.74 + end 14.75 + end } 14.76 + 14.77 +end } 14.78 + 14.79 +ui.box_col{ class = "time_left", content = issue.closed and _("Closed since #{date}", { date = format.date(issue.closed.date) }) or _("#{time_left} left", { time_left = issue.state_time_left }) } 14.80 +
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/app/main/lf2/_search.lua Wed Mar 02 20:06:26 2011 +0100 15.3 @@ -0,0 +1,35 @@ 15.4 +ui.container{ 15.5 + attr = { class = "boxhead" }, 15.6 + content = _"Search in initiatives for text:" 15.7 +} 15.8 + 15.9 +ui.container{ 15.10 + attr = { class = "search box" }, 15.11 + content = function() 15.12 + ui.container{ 15.13 + attr = { class = "row first" }, 15.14 + content = function() 15.15 + ui.container{ 15.16 + attr = { class = "col first" }, 15.17 + content = function() 15.18 + 15.19 + ui.form{ 15.20 + content = function() 15.21 + 15.22 + 15.23 + slot.put(" ") 15.24 + 15.25 + ui.tag{ tag = "input", attr = { type = "text", name = "q" } } 15.26 + 15.27 + ui.submit{ text = _"Search" } 15.28 + 15.29 + end 15.30 + } 15.31 + 15.32 + end 15.33 + } 15.34 + 15.35 + end 15.36 + } 15.37 + end 15.38 +} 15.39 \ No newline at end of file
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/app/main/lf2/_sidebar.lua Wed Mar 02 20:06:26 2011 +0100 16.3 @@ -0,0 +1,36 @@ 16.4 +local member_areas_selector = Area:build_selector{ 16.5 + member_id = app.session.member_id, 16.6 + order = "name" 16.7 +} 16.8 +local other_areas_selector = Area:build_selector{ 16.9 + not_member_id = app.session.member_id, 16.10 + order = "name" 16.11 +} 16.12 + 16.13 +execute.view{ module = "lf2", view = "_delegation_global" } 16.14 + 16.15 +ui.form{ 16.16 + content = function() 16.17 + 16.18 + ui.container{ attr = { class = "boxhead" }, content = _"" } 16.19 + --execute.view{ module = "lf2", view = "_areas", params = { areas_selector = member_areas_selector } } 16.20 + 16.21 + execute.view{ 16.22 + module = "lf2", view = "_areas", params = { 16.23 + areas_selector = member_areas_selector, 16.24 + head_content = function() ui.tag{ content = _"Areas, you are member of" } end 16.25 + } 16.26 + } 16.27 + 16.28 + execute.view{ 16.29 + module = "lf2", view = "_areas", params = { 16.30 + areas_selector = other_areas_selector, 16.31 + head_content = function() ui.tag{ content = _"Areas, you are not member of" } end 16.32 + } 16.33 + } 16.34 + 16.35 + end 16.36 +} 16.37 + 16.38 +execute.view{ module = "lf2", view = "_search", params = { area = area } } 16.39 +
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/app/main/lf2/_sidebar_drafts.lua Wed Mar 02 20:06:26 2011 +0100 17.3 @@ -0,0 +1,55 @@ 17.4 +local initiative = param.get("initiative", "table") 17.5 + 17.6 +local drafts = Draft:new_selector() 17.7 + :add_where{ "draft.initiative_id = ?", initiative.id } 17.8 + :add_order_by("id DESC") 17.9 + :exec() 17.10 + 17.11 +ui.container{ attr = { class = "boxhead" }, content = _"Draft revisions" } 17.12 + 17.13 +ui.box{ class = "drafts", content = function() 17.14 + if drafts then 17.15 + ui.form{ 17.16 + method = "get", 17.17 + module = "draft", 17.18 + view = "diff", 17.19 + content = function() 17.20 + ui.box_row{ class = "", content = function() 17.21 + ui.box_col{ class = "scrolled", content = function() 17.22 + 17.23 + for i, draft in ipairs(drafts) do 17.24 + ui.box_row{ class = "draft", content = function() 17.25 + ui.box_col{ class = "left", content = function() 17.26 + ui.link{ 17.27 + attr = { class = "created" }, 17.28 + text = format.timestamp(draft.created), 17.29 + module = "draft", 17.30 + view = "show", 17.31 + id = draft.id 17.32 + } 17.33 + slot.put("<br />") 17.34 + ui.tag{ content = _"by" } 17.35 + slot.put(" ") 17.36 + ui.link{ 17.37 + attr = { class = "author_name" }, 17.38 + module = "lf2", view = "issue", id = initiative.issue_id, 17.39 + params = { member_id = author_id }, 17.40 + text = draft.author.name 17.41 + } 17.42 + end } 17.43 + ui.box_col{ class = "right", content = function() 17.44 + slot.put('<input type="radio" name="old_draft_id" value="' .. tostring(draft.id) .. '">') 17.45 + slot.put('<input type="radio" name="new_draft_id" value="' .. tostring(draft.id) .. '">') 17.46 + end } 17.47 + end } 17.48 + end 17.49 + end } end } 17.50 + 17.51 + ui.box_row{ content = function() ui.box_col{ class = "right", content = function() 17.52 + ui.submit{ text = _"Compare selected" } 17.53 + end } end } 17.54 + end 17.55 + } 17.56 + else 17.57 + end 17.58 +end }
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/app/main/lf2/_sidebar_initiatives.lua Wed Mar 02 20:06:26 2011 +0100 18.3 @@ -0,0 +1,9 @@ 18.4 +local initiatives = param.get("initiatives", "table") 18.5 +ui.box{ content = function() 18.6 + ui.box_row{ class = "initiatives", content = function() 18.7 + ui.box_col{ class = "scrolled", content = function() 18.8 + execute.view{ module = "lf2", view = "_issue_initiatives", params = { initiatives = initiatives } } 18.9 + end } 18.10 + end } 18.11 +end } 18.12 +
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/app/main/lf2/_sidebar_issue.lua Wed Mar 02 20:06:26 2011 +0100 19.3 @@ -0,0 +1,177 @@ 19.4 +local issue = param.get("issue", "table") 19.5 + 19.6 +local initiatives = issue.initiatives 19.7 + 19.8 +local interested_members_selector = Member:new_selector() 19.9 + :join("direct_interest_snapshot", "dis", { "dis.issue_id = ? AND dis.member_id = member.id and dis.event = (select latest_snapshot_event from issue where id = ?)", issue.id, issue.id }) 19.10 + :add_field("dis.weight", "weight") 19.11 + :add_order_by("dis.weight DESC") 19.12 +local interested_members = interested_members_selector:exec() 19.13 + 19.14 +local interest = issue.interest 19.15 + 19.16 +local delegations = issue.delegations 19.17 + 19.18 +local trustees = Member:new_selector() 19.19 + :add_field("delegation_chain.*") 19.20 + :join("delegation_chain(" .. tostring(app.session.member.id) .. ", NULL, " .. tostring(issue.id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id") 19.21 + :add_order_by("index") 19.22 + :exec() 19.23 + 19.24 +local global_delegation 19.25 +local area_delegation 19.26 +local issue_delegation 19.27 + 19.28 +for i, delegation in ipairs(issue.delegations) do 19.29 + if delegation.scope == "global" then global_delegation = delegation 19.30 + elseif delegation.scope == "area" then area_delegation = delegation 19.31 + elseif delegation.scope == "issue" then issue_delegation = delegation 19.32 + end 19.33 +end 19.34 + 19.35 +local delegation = issue_delegation or area_delegation or global_delegation 19.36 + 19.37 +local delegating_interest = issue.delegating_interest 19.38 + 19.39 +ui.box{ class = "issue", content = function() 19.40 + 19.41 + ui.box_row{ class = "issue_id head", content = function() ui.box_col{ content = function() 19.42 + ui.link{ 19.43 + module = "lf2", view = "issue", id = issue.id, 19.44 + content = _("Issue ##{id}", { id = issue.id }) 19.45 + } 19.46 + end } end } 19.47 + 19.48 + ui.box_row{ class = "unit_name", content = function() ui.box_col{ content = function() 19.49 + ui.link{ 19.50 + module = "lf2", view = "unit", id = 1, 19.51 + content = "DE / Berlin / Friedrichshain-Kreuzberg" 19.52 + } 19.53 + end } end } 19.54 + 19.55 + ui.box_row{ class = "area_name", content = function() ui.box_col{ content = function() 19.56 + ui.link{ 19.57 + module = "lf2", view = "area", id = issue.area_id, 19.58 + content = issue.area.name 19.59 + } 19.60 + end } end } 19.61 + 19.62 + ui.box_row{ class = "policy_name", content = function() ui.box_col{ content = function() 19.63 + ui.link{ 19.64 + module = "lf2", view = "policy", id = issue.policy_id, 19.65 + content = issue.policy.name 19.66 + } 19.67 + end } end } 19.68 + 19.69 + ui.box_row{ class = "time_left", content = function() 19.70 + ui.box_col{ content = issue.closed and _("Closed since #{date}", { date = format.date(issue.closed.date) }) or _("#{time_left} left", { time_left = issue.state_time_left }) } 19.71 + end } 19.72 + 19.73 + ui.box_row{ class = "interest hoverbutton_container", content = function() ui.box_col{ content = function() 19.74 + if interest then 19.75 + ui.image{ static = "lf2/icon_star.png" } 19.76 + if issue.closed then 19.77 + slot.put(" ", _"You were interested in this issue") 19.78 + else 19.79 + slot.put(" ", _"You are interested in this issue") 19.80 + end 19.81 + else 19.82 + ui.image{ static = "lf2/icon_star_grey.png" } 19.83 + slot.put(_"You are not interested in this issue") 19.84 + end 19.85 + 19.86 + if issue.closed then 19.87 + ui.container{ attr = { class = "hoverbutton noaction"}, content = function() 19.88 + ui.container{ attr = { class = "content"}, content = function() 19.89 + slot.put(" ", encode.html(_"This issue is closed")) 19.90 + end } 19.91 + end } 19.92 + elseif issue.fully_frozen then 19.93 + ui.container{ attr = { class = "hoverbutton noaction"}, content = function() 19.94 + ui.container{ attr = { class = "content"}, content = function() 19.95 + slot.put(" ", encode.html(_"This issue is in voting")) 19.96 + end } 19.97 + end } 19.98 + else 19.99 + if interest then 19.100 + ui.link{ 19.101 + module = "interest", action = "update", params = { issue_id = issue.id, delete = true }, 19.102 + routing = { default = { 19.103 + mode = "redirect", module = "lf2", view = "issue", id = issue.id 19.104 + } }, 19.105 + attr = { class = "hoverbutton red"}, 19.106 + content = function() 19.107 + ui.container{ attr = { class = "content"}, content = function() 19.108 + ui.image{ static = "lf2/icon_star_crossed.png" } 19.109 + slot.put(" ", encode.html(_"Remove my interest")) 19.110 + end } 19.111 + end 19.112 + } 19.113 + 19.114 + else 19.115 + ui.link{ 19.116 + module = "interest", action = "update", params = { issue_id = issue.id }, 19.117 + routing = { default = { 19.118 + mode = "redirect", module = "lf2", view = "issue", id = issue.id 19.119 + } }, 19.120 + attr = { class = "hoverbutton green"}, 19.121 + content = function() 19.122 + ui.container{ attr = { class = "content"}, content = function() 19.123 + ui.image{ static = "lf2/icon_star.png" } 19.124 + slot.put(" ", encode.html(_"Add my interest")) 19.125 + end 19.126 + } 19.127 + end } 19.128 + 19.129 + end 19.130 + end 19.131 + end } end } 19.132 + 19.133 + ui.box_row{ class = "delegation hoverbutton_container", content = function() ui.box_col{ content = function() 19.134 + if delegation then 19.135 + if delegation.issue_id then 19.136 + slot.put(encode.html(_"You have delegated this issue")) 19.137 + elseif delegation.area_id then 19.138 + slot.put(encode.html(_"You have delegated this area")) 19.139 + elseif delegation then 19.140 + slot.put(encode.html(_"You have delegated globally")) 19.141 + end 19.142 + else 19.143 + slot.put(encode.html(_"No delegation active")) 19.144 + end 19.145 + 19.146 + if issue.closed then 19.147 + ui.container{ attr = { class = "hoverbutton noaction"}, content = function() 19.148 + ui.container{ attr = { class = "content"}, content = function() 19.149 + slot.put(" ", encode.html(_"This issue is closed")) 19.150 + end } 19.151 + end } 19.152 + else 19.153 + if delegation then 19.154 + ui.link{ attr = { class = "hoverbutton red"}, content = function() 19.155 + ui.container{ attr = { class = "content"}, content = function() 19.156 + ui.image{ static = "lf2/icon_delegation.png" } 19.157 + slot.put(" ", encode.html(_"Change delegation...")) 19.158 + end } 19.159 + end } 19.160 + 19.161 + else 19.162 + ui.link{ attr = { class = "hoverbutton green"}, content = function() 19.163 + ui.container{ attr = { class = "content"}, content = function() 19.164 + ui.image{ static = "lf2/icon_delegation.png" } 19.165 + slot.put(" ", encode.html(_"Delegate issue")) 19.166 + end } 19.167 + end } 19.168 + 19.169 + end 19.170 + end 19.171 + 19.172 + end } end } 19.173 + 19.174 + if delegation then 19.175 + ui.box_row{ class = "delegation", content = function() ui.box_col{ content = function() 19.176 + execute.view{ module = "lf2", view = "_avatars", params = { members = trustees, arrows = true, size = "small" } } 19.177 + end } end } 19.178 + end 19.179 + 19.180 +end }
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/app/main/lf2/area.lua Wed Mar 02 20:06:26 2011 +0100 20.3 @@ -0,0 +1,24 @@ 20.4 +local area = Area:by_id(param.get_id()) 20.5 + 20.6 +slot.set_layout("lf2") 20.7 + 20.8 +slot.select("sidebar", function() 20.9 + execute.view{ module = "lf2", view = "_sidebar" } 20.10 +end) 20.11 + 20.12 +execute.view{ module = "lf2", view = "_area", params = { area = area } } 20.13 + 20.14 + 20.15 +local issues_selector = Issue:build_selector{ 20.16 + area_id = area.id, 20.17 + state = param.get("state"), 20.18 + order = param.get("order") 20.19 +}:limit(25) 20.20 + 20.21 +local issues = issues_selector:exec() 20.22 + 20.23 +issues:load("delegating_interest_snapshot_for_member", { member_id = app.session.member_id }, "delegating_interest") 20.24 +issues:load("interest_for_member", { member_id = app.session.member_id }, "interest") 20.25 +issues:load("outgoing_delegations_for_member", { member_id = app.session.member_id }, "outgoing_delegations") 20.26 + 20.27 +execute.view{ module = "lf2", view = "_issues", params = { issues = issues } }
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 21.2 +++ b/app/main/lf2/area_notification.lua Wed Mar 02 20:06:26 2011 +0100 21.3 @@ -0,0 +1,11 @@ 21.4 +local area = Area:by_id(param.get_id()) 21.5 + 21.6 +slot.set_layout("lf2") 21.7 + 21.8 +ui.box{ 21.9 + ui.box_row{ content = function() ui.box_col{ content = function() 21.10 + 21.11 + 21.12 + 21.13 + end } end } 21.14 +} 21.15 \ No newline at end of file
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/app/main/lf2/index.lua Wed Mar 02 20:06:26 2011 +0100 22.3 @@ -0,0 +1,18 @@ 22.4 +slot.set_layout("lf2") 22.5 + 22.6 +slot.select("sidebar", function() 22.7 + execute.view{ module = "lf2", view = "_sidebar" } 22.8 +end) 22.9 + 22.10 +local issues_selector = Issue:build_selector{ 22.11 + state = param.get("state"), 22.12 + order = param.get("order") 22.13 +}:limit(25) 22.14 + 22.15 +local issues = issues_selector:exec() 22.16 + 22.17 +issues:load("delegating_interest_snapshot_for_member", { member_id = app.session.member_id }, "delegating_interest") 22.18 +issues:load("interest_for_member", { member_id = app.session.member_id }, "interest") 22.19 +issues:load("outgoing_delegations_for_member", { member_id = app.session.member_id }, "outgoing_delegations") 22.20 + 22.21 +execute.view{ module = "lf2", view = "_issues", params = { issues = issues } }
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/app/main/lf2/initiative.lua Wed Mar 02 20:06:26 2011 +0100 23.3 @@ -0,0 +1,92 @@ 23.4 +slot.set_layout("lf2") 23.5 + 23.6 +local initiative = Initiative:by_id(param.get_id()) 23.7 + 23.8 +local issue = initiative.issue 23.9 + 23.10 +local supporting_members_selector = Member:new_selector() 23.11 + :join("direct_supporter_snapshot", "dss", { "dss.issue_id = ? AND dss.initiative_id = ? AND dss.member_id = member.id and dss.event = (select latest_snapshot_event from issue where id = ?)", issue.id, initiative.id, issue.id }) 23.12 + :join("direct_interest_snapshot", "dis", { "dis.issue_id = ? AND dis.member_id = member.id and dis.event = (select latest_snapshot_event from issue where id = ?)", issue.id, issue.id }) 23.13 + :add_field("dis.weight", "weight") 23.14 + :add_order_by("dis.weight DESC") 23.15 +local supporting_members = supporting_members_selector:exec() 23.16 + 23.17 +local voting_members_selector = Member:new_selector() 23.18 + :join("direct_voter", nil, { "direct_voter.issue_id = ? AND direct_voter.member_id = member.id", issue.id }) 23.19 + :add_field("direct_voter.weight", "weight") 23.20 + :add_order_by("direct_voter.weight DESC") 23.21 +local voting_members = voting_members_selector:exec() 23.22 + 23.23 +local alternative_initiatives = initiative.issue.initiatives 23.24 +alternative_initiatives:load("initiating_members", nil, "initiating_members") 23.25 + 23.26 + 23.27 +slot.select("sidebar", function() 23.28 + 23.29 + execute.view{ module = "lf2", view = "_sidebar_issue", params = { issue = issue } } 23.30 + ui.container{ attr = { class = "boxhead" }, content = _"Alternative initiatives" } 23.31 + 23.32 + execute.view{ module = "lf2", view = "_sidebar_initiatives", params = { 23.33 + initiatives = alternative_initiatives 23.34 + } } 23.35 + 23.36 + execute.view{ module = "lf2", view = "_sidebar_drafts", params = { 23.37 + initiative = initiative 23.38 + } } 23.39 + 23.40 +end) 23.41 + 23.42 +local draft = initiative.current_draft 23.43 + 23.44 +ui.box{ 23.45 + content = function() 23.46 + 23.47 + ui.box_row{ class = "initiative head", content = function() ui.box_col { content = function() 23.48 + execute.view{ module = "lf2", view = "_initiative", params = { initiative = initiative } } 23.49 + end } end } 23.50 + 23.51 + ui.box_row{ class = "head2", content = function() ui.box_col{ content = function() 23.52 + if initiative.issue.fully_frozen and initiative.issue.closed then 23.53 + ui.link{ external = "#votes", text = _("#{vote_count} votes", { vote_count = #voting_members }) } 23.54 + slot.put(" · ") 23.55 + end 23.56 + ui.link{ external = "#suggestions", text = _("#{suggestion_count} suggestions", { suggestion_count = 23 }) } 23.57 + slot.put(" · ") 23.58 + ui.link{ external = "#supporters", text = _("#{supporter_count} supporters", { supporter_count = #supporting_members }) } 23.59 + end } end } 23.60 + 23.61 + ui.box_row{ content = function() ui.box_col{ content = function() 23.62 + execute.view{ module = "lf2", view = "_draft", params = { draft = draft } } 23.63 + end } end } 23.64 + end 23.65 +} 23.66 + 23.67 +if initiative.issue.fully_frozen and initiative.issue.closed then 23.68 + ui.boxhead{ name = "votes", content = _"Votes" } 23.69 + ui.box{ 23.70 + content = function() 23.71 + ui.box_row{ content = function() ui.box_col{ content = function() 23.72 + execute.view{ module = "lf2", view = "_avatars", params = { members = voting_members } } 23.73 + end } end } 23.74 + end 23.75 + } 23.76 +end 23.77 + 23.78 +ui.boxhead{ name = "suggestions", content = _"Suggestions" } 23.79 +ui.box{ 23.80 + content = function() 23.81 + ui.box_row{ content = function() ui.box_col{ content = function() 23.82 + slot.put("suggestions") 23.83 + end } end } 23.84 + end 23.85 +} 23.86 + 23.87 +ui.boxhead{ name = "supporters", content = _"Supporters" } 23.88 +ui.box{ 23.89 + content = function() 23.90 + ui.box_row{ content = function() ui.box_col{ content = function() 23.91 + execute.view{ module = "lf2", view = "_avatars", params = { members = supporting_members } } 23.92 + end } end } 23.93 + end 23.94 +} 23.95 +
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/app/main/lf2/issue.lua Wed Mar 02 20:06:26 2011 +0100 24.3 @@ -0,0 +1,56 @@ 24.4 +slot.set_layout("lf2") 24.5 + 24.6 + 24.7 +local issue = Issue:by_id(param.get_id()) 24.8 +local area = issue.area 24.9 + 24.10 +-- TODO broken 24.11 +--issue:load("interested_members_snapshot", {}, "interested_members") 24.12 +issue:load("delegating_interest_snapshot_for_member", { member_id = app.session.member_id }, "delegating_interest") 24.13 +issue:load("interest_for_member", { member_id = app.session.member_id }, "interest") 24.14 +issue:load("outgoing_delegations_for_member", { member_id = app.session.member_id }, "outgoing_delegations") 24.15 + 24.16 +local initiatives = issue.initiatives 24.17 + 24.18 +local interested_members = issue.interested_members 24.19 + 24.20 +local interest = issue.interest 24.21 + 24.22 +local delegations = issue.delegations 24.23 + 24.24 +local trustees = Member:new_selector() 24.25 + :add_field("delegation_chain.*") 24.26 + :join("delegation_chain(" .. tostring(app.session.member.id) .. ", " .. tostring(area_id or "NULL") .. ", " .. tostring(issue_id or "NULL") .. ")", "delegation_chain", "member.id = delegation_chain.member_id") 24.27 + :add_order_by("index") 24.28 + :exec() 24.29 + 24.30 +local global_delegation 24.31 +local area_delegation 24.32 +local issue_delegation 24.33 + 24.34 +for i, delegation in ipairs(issue.delegations) do 24.35 + if delegation.scope == "global" then global_delegation = delegation 24.36 + elseif delegation.scope == "area" then area_delegation = delegation 24.37 + elseif delegation.scope == "issue" then issue_delegation = delegation 24.38 + end 24.39 +end 24.40 + 24.41 +local delegation = issue_delegation or area_delegation or global_delegation 24.42 + 24.43 +local delegating_interest = issue.delegating_interest 24.44 + 24.45 +slot.select("sidebar", function() 24.46 + execute.view{ module = "lf2", view = "_sidebar" } 24.47 +end) 24.48 + 24.49 +execute.view{ module = "lf2", view = "_area", params = { area = area } } 24.50 + 24.51 +execute.view{ module = "lf2", view = "_issues", params = { issues = { issue } } } 24.52 + 24.53 +-- TODO bugfix for not working reference loader 24.54 +interested_members = issue:get_reference_selector("interested_members_snapshot"):exec() 24.55 + 24.56 +execute.view{ module = "lf2", view = "_interested", params = { 24.57 + interested_members = interested_members 24.58 +} } 24.59 +
25.1 --- a/config/development.lua Sat Feb 05 20:01:09 2011 +0100 25.2 +++ b/config/development.lua Wed Mar 02 20:06:26 2011 +0100 25.3 @@ -3,7 +3,7 @@ 25.4 execute.config("default") 25.5 25.6 config.formatting_engine_executeables = { 25.7 - rocketwiki= "/opt/rocketwiki/rocketwiki-lqfb", 25.8 + rocketwiki= "/opt/rocketwiki/rocketwiki-lqfb.sh", 25.9 compat = "/opt/rocketwiki/rocketwiki-lqfb-compat" 25.10 } 25.11
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/env/ui/avatar.lua Wed Mar 02 20:06:26 2011 +0100 26.3 @@ -0,0 +1,66 @@ 26.4 +local alphabet = { 26.5 + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", 26.6 + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", 26.7 + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", 26.8 + "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 26.9 + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/" 26.10 +} 26.11 + 26.12 +local function encode_base64(str) 26.13 + local parts = {} 26.14 + local pos = 1 26.15 + local block_count = 0 26.16 + while pos <= #str do 26.17 + local s = string.sub(str, pos, pos + 2) 26.18 + local n = 0 26.19 + for i = 1, 3 do 26.20 + n = n * 256 26.21 + if i <= #s then 26.22 + n = n + string.byte(string.sub(s, i, i)) 26.23 + end 26.24 + end 26.25 + parts[#parts+1] = alphabet[math.floor(n / 262144) + 1] 26.26 + parts[#parts+1] = alphabet[math.floor(n / 4096) % 64 + 1] 26.27 + if #s > 1 then 26.28 + parts[#parts+1] = alphabet[math.floor(n / 64) % 64 + 1] 26.29 + else 26.30 + parts[#parts+1] = "=" 26.31 + end 26.32 + if #s > 2 then 26.33 + parts[#parts+1] = alphabet[n % 64 + 1] 26.34 + else 26.35 + parts[#parts+1] = "=" 26.36 + end 26.37 + block_count = block_count + 1 26.38 + if block_count == 19 then 26.39 + --parts[#parts+1] = "\r\n" 26.40 + block_count = 0 26.41 + end 26.42 + pos = pos + #s 26.43 + end 26.44 + if block_count > 0 then 26.45 + --parts[#parts+1] = "\r\n" 26.46 + end 26.47 + return table.concat(parts) 26.48 +end 26.49 + 26.50 +function ui.avatar(member, size) 26.51 + local base64_string 26.52 + 26.53 + if member.avatar_base64 then 26.54 + base64_string = member.avatar_base64 26.55 + else 26.56 + local member_image = MemberImage:by_pk(member.id, "avatar", true) 26.57 + if member_image then 26.58 + base64_string = encode_base64(member_image.data) 26.59 + else 26.60 + base64_string = "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/wAALCAAwADABAREA/8QAGQABAAMBAQAAAAAAAAAAAAAAAAMGBwQC/8QAIxAAAgICAgEEAwAAAAAAAAAAAQIAAwQRBTEGEiEyYTVRcf/aAAgBAQAAPwDf4kN2TRjjd1ip/TFOTRkDdNiv/DJoiR3WCml7D0o3M55DOtzsp7HYkb9h+hHH51uDlJYjEDfuP2Jo1NgupSwdMNySJzcgC3H3gd+gzNCNMR9wBtgPuaXx4K8fQD36BOmJ5ZQ6FT0RozNeQrWrPuRegx1HH1rbn0o3RYbmlKoRAo6A0J6kGXlV4eM99vxXuVrK8uJBXHp19tKxZY1trWN8mOzFdjVWrYvyU7Es+L5cQAuRTv7WWXEyq8zGS+r4t1ODyP8AC3SgRES/+OfhaZ//2Q==" 26.61 + end 26.62 + member.avatar_base64 = base64_string 26.63 + member:save() 26.64 + end 26.65 + 26.66 + ui.tag{ tag = "img", attr = { src = "data:image/jpeg;base64," .. base64_string } } 26.67 + 26.68 +end 26.69 +
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/env/ui/box.lua Wed Mar 02 20:06:26 2011 +0100 27.3 @@ -0,0 +1,7 @@ 27.4 +function ui.box(args) 27.5 + app.ui_box_row = 1 27.6 + app.ui_box_row_count = args.row_count 27.7 + local class = "box" 27.8 + if args.class then class = class .. " " .. args.class end 27.9 + ui.container{ attr = { class = class }, content = args.content } 27.10 +end
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 28.2 +++ b/env/ui/box_col.lua Wed Mar 02 20:06:26 2011 +0100 28.3 @@ -0,0 +1,7 @@ 28.4 +function ui.box_col(args) 28.5 + local class = "col" 28.6 + if args.class then class = class .. " " .. args.class end 28.7 + if app.ui_box_col == 1 then class = class .. " first" end 28.8 + ui.container{ attr = { class = class }, content = args.content } 28.9 + app.ui_box_col = app.ui_box_col + 1 28.10 +end
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/env/ui/box_row.lua Wed Mar 02 20:06:26 2011 +0100 29.3 @@ -0,0 +1,25 @@ 29.4 +function ui.box_row(args) 29.5 + app.ui_box_col = 1 29.6 + local class = "row" 29.7 + if args.class then class = class .. " " .. args.class end 29.8 + if app.ui_box_row == 1 then class = class .. " first" end 29.9 + if app.ui_box_row == app.ui_box_row_count then class = class .. " last" end 29.10 + if args.toggle_content then class = class .. " toggled" end 29.11 + ui.container{ attr = { class = class }, content = function() 29.12 + if args.toggle_content then 29.13 + ui.container{ attr = { class = "col toggle"}, content = function() 29.14 + if type(args.toggle_content) == "function" then 29.15 + args.toggle_content() 29.16 + else 29.17 + slot.put(encode.html(args.toggle_content)) 29.18 + end 29.19 + end } 29.20 + end 29.21 + if type(args.content) == "function" then 29.22 + args.content() 29.23 + else 29.24 + slot.put(encode.html(args.content)) 29.25 + end 29.26 + end } 29.27 + app.ui_box_row = app.ui_box_row + 1 29.28 +end
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 30.2 +++ b/env/ui/boxhead.lua Wed Mar 02 20:06:26 2011 +0100 30.3 @@ -0,0 +1,5 @@ 30.4 +function ui.boxhead(args) 30.5 + local class = "boxhead" 30.6 + if args.class then class = class .. " " .. args.class end 30.7 + ui.tag{ tag = "a", attr = { class = class, name = args.name }, content = args.content } 30.8 +end
31.1 --- a/locale/translations.de.lua Sat Feb 05 20:01:09 2011 +0100 31.2 +++ b/locale/translations.de.lua Wed Mar 02 20:06:26 2011 +0100 31.3 @@ -3,14 +3,20 @@ 31.4 ["##{id}"] = "##{id}"; 31.5 ["##{issue_id}.#{id} #{name}"] = "##{issue_id}.#{id} #{name}"; 31.6 ["#{author} at #{date}"] = "#{author} am #{date}"; 31.7 +["#{direct_count}+#{delegated_count} Mitglieder"] = false; 31.8 ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = "#{interested_issues_to_vote_count} Themen, die Dich interessieren"; 31.9 ["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} Themen"; 31.10 ["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht"; 31.11 ["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert"; 31.12 +["#{suggestion_count} suggestions"] = "#{suggestion_count} Anregungen"; 31.13 +["#{supporter_count} supporters"] = "#{supporter_count} Unterstützer"; 31.14 +["#{time_left} left"] = "noch #{time_left}"; 31.15 +["#{vote_count} votes"] = "#{vote_count} Stimmzettel"; 31.16 ["(#{more_count} duplicates removed)"] = "(#{more_count} Duplikate entfernt)"; 31.17 ["(change URL)"] = "(URL ändern)"; 31.18 ["(new window)"] = "(neues Fenster)"; 31.19 ["+ #{weight}"] = "+ #{weight}"; 31.20 +["+getElementById("] = false; 31.21 ["A-Z"] = "A-Z"; 31.22 ["API key"] = "API-Schlüssel"; 31.23 ["API key has been deleted"] = "API-Schlüssel wurde gelöscht"; 31.24 @@ -62,6 +68,8 @@ 31.25 ["Area list"] = "Liste der Themenbereiche"; 31.26 ["Area successfully updated"] = "Themenbereich erfolgreich aktualisiert"; 31.27 ["Areas"] = "Themenbereiche"; 31.28 +["Areas, you are member of"] = false; 31.29 +["Areas, you are not member of"] = "Nicht Mitglied in:"; 31.30 ["Author"] = "Autor"; 31.31 ["Auto support is now disabled"] = false; 31.32 ["Auto support is now enabled"] = false; 31.33 @@ -77,6 +85,7 @@ 31.34 ["Back to timeline"] = "Zurück zur Zeitachse"; 31.35 ["Ballot of '#{member_name}' for issue ##{issue_id}"] = "Stimmzettel von '#{member_name}' für Thema ##{issue_id}"; 31.36 ["Become a member"] = "Mitglied werden"; 31.37 +["Become a member of this area"] = "Dem Themenbereich beitreten"; 31.38 ["Birthday"] = "Geburtstag"; 31.39 ["Can't remove last initiator"] = "Der letzte Initiator kann nicht entfernt werden"; 31.40 ["Can't send confirmation email"] = "Bestätigungs-E-Mail kann nicht versendet werden."; 31.41 @@ -87,6 +96,7 @@ 31.42 ["Cancelled"] = "Abgebrochen"; 31.43 ["Change API key"] = "API-Schlüssel ändern"; 31.44 ["Change area delegation"] = "Delegation für Themenbereich ändern"; 31.45 +["Change delegation..."] = "Delegation ändern..."; 31.46 ["Change display settings"] = "Anzeige-Einstellungen ändern"; 31.47 ["Change email"] = "E-Mail-Adresse ändern"; 31.48 ["Change email address"] = "E-Mail-Adresse ändern"; 31.49 @@ -106,9 +116,11 @@ 31.50 ["Choose member"] = "Mitglied auswählen"; 31.51 ["Click for details"] = "Klicke für Details"; 31.52 ["Closed"] = "geschlossen"; 31.53 +["Closed since #{date}"] = "Geschlossen seit #{date}"; 31.54 ["Collective opinion of supporters"] = "Meinungsbild der Unterstützer"; 31.55 ["Commit suggestion"] = "Anregung speichern"; 31.56 ["Compare"] = "Vergleichen"; 31.57 +["Compare selected"] = "Vergleiche ausgewählte"; 31.58 ["Confirm"] = "Bestätigen"; 31.59 ["Confirmation code"] = "Bestätigungscode"; 31.60 ["Confirmation code invalid!"] = "Bestätigungscode ist ungültig!"; 31.61 @@ -133,6 +145,8 @@ 31.62 ["Date format is not valid. Please use following format: YYYY-MM-DD"] = "Datumsformat nicht korrekt. Bitte verwende: JJJJ-MM-TT, also z.B. 1945-05-23"; 31.63 ["Default Policy"] = "Standard-Regelwerk"; 31.64 ["Degree"] = "Grad"; 31.65 +["Delegate area..."] = "Themengebiet delegieren..."; 31.66 +["Delegate issue"] = "Thema delegieren"; 31.67 ["Delegation abandoned"] = "Delegation ausgesetzt"; 31.68 ["Delegation problems"] = "Delegationsprobleme"; 31.69 ["Delegation turned off for area"] = "Delegation für Themengebiet ausgesetzt"; 31.70 @@ -166,6 +180,7 @@ 31.71 ["Download database export"] = "Datenbankexport herunterladen"; 31.72 ["Draft"] = "Entwurf"; 31.73 ["Draft history"] = "Entwurfshistorie"; 31.74 +["Draft revisions"] = "Entwurfsversionen"; 31.75 ["EXPERIMENTAL FEATURE"] = "EXPERIMENTELLE FUNKTION"; 31.76 ["Edit"] = "Bearbeiten"; 31.77 ["Edit draft"] = "Entwurf bearbeiten"; 31.78 @@ -193,6 +208,7 @@ 31.79 ["Fully frozen at"] = "Ganz eingefroren am/um"; 31.80 ["Generate / change API key"] = "API-Schlüssel erzeugen/ändern"; 31.81 ["Generate API key"] = "API-Schlüssel erzeugen"; 31.82 +["Give up membership"] = "Mitgliedschaft aufgeben"; 31.83 ["Global delegation"] = "Globale Delegation"; 31.84 ["Global delegation active"] = "Globale Delegation aktiv"; 31.85 ["Go up"] = "Nach oben"; 31.86 @@ -222,6 +238,8 @@ 31.87 ["Initiative ##{id}"] = "Initiative ##{id}"; 31.88 ["Initiative events"] = "Initiativen-Ereignisse"; 31.89 ["Initiative is revoked now"] = "Initiative ist jetzt zurückgezogen"; 31.90 +["Initiative not admitted"] = "Initiative nicht zugelassen"; 31.91 +["Initiative not agreed"] = "Initiative abgelehnt"; 31.92 ["Initiative quorum"] = "Quorum Inititive"; 31.93 ["Initiative quorum denumerator"] = "Initiativ-Quorum Zähler"; 31.94 ["Initiative quorum numerator"] = "Initiativ-Quorum Nenner"; 31.95 @@ -239,6 +257,7 @@ 31.96 ["Initiator"] = "Initiator"; 31.97 ["Initiator invites"] = "Einladungen"; 31.98 ["Initiators"] = "Initiatoren"; 31.99 +["Interest"] = "Interesse"; 31.100 ["Interest not existant"] = "Interesse existiert nicht"; 31.101 ["Interest removed"] = "Interesse entfernt"; 31.102 ["Interest updated"] = "Interesse aktualisiert"; 31.103 @@ -263,6 +282,7 @@ 31.104 ["Issue finished"] = "Thema abgeschlossen"; 31.105 ["Issue finished without voting"] = "Thema ohne Abstimmung abgeschlossen"; 31.106 ["Issue frozen"] = "Thema eingefroren"; 31.107 +["Issue not accepted"] = "Thema nicht zugelassen"; 31.108 ["Issue policy"] = "Regelwerk für Thema"; 31.109 ["Issue quorum"] = "Quorum Thema"; 31.110 ["Issue quorum denumerator"] = "Themen-Quorum Zähler"; 31.111 @@ -270,6 +290,8 @@ 31.112 ["Issues"] = "Themen"; 31.113 ["JavaScript is disabled or not available."] = "JavaScript ist abgeschaltet oder nicht verfügbar."; 31.114 ["Last author"] = "Letzter Autor"; 31.115 +["Last change"] = "Letzte Änderung"; 31.116 +["Last login (updated daily)"] = "Letzte Anmeldung (täglich aktualisiert)"; 31.117 ["Last snapshot:"] = "Letzte Auszählung:"; 31.118 ["Legend:"] = "Legende:"; 31.119 ["License"] = "Lizenz"; 31.120 @@ -336,6 +358,7 @@ 31.121 ["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert"; 31.122 ["No default"] = "Kein Standard"; 31.123 ["No delegation"] = "Keine Delegation"; 31.124 +["No delegation active"] = "Keine Delegation aktiv"; 31.125 ["No events selected to list"] = "Keine Ereignisse ausgewählt"; 31.126 ["No membership at all"] = "Gar keine Mitgliedschaft"; 31.127 ["No support at all"] = "Gar keine Unterstützung"; 31.128 @@ -442,6 +465,7 @@ 31.129 ["Saved as contact"] = "Als Kontakt gespeichert"; 31.130 ["Saved contacts"] = "Gespeicherte Kontakte"; 31.131 ["Search"] = "Suchen"; 31.132 +["Search in initiatives for text:"] = "In Initiative nach Text suchen:"; 31.133 ["Search initiatives"] = "Suche Initiativen"; 31.134 ["Search issues"] = "Suche Themen"; 31.135 ["Search members"] = "Suche Mitglieder"; 31.136 @@ -507,6 +531,7 @@ 31.137 ["Supported"] = "Unterstützt"; 31.138 ["Supported initiatives"] = "Unterstützte Initiativen"; 31.139 ["Supporter"] = "Unterstützer"; 31.140 +["Supporters"] = "Unterstützer"; 31.141 ["Syntax help"] = "Syntax-Hilfe"; 31.142 ["Tabs"] = "Registerkarten"; 31.143 ["Terms of use"] = "Nutzungsbedingungen"; 31.144 @@ -515,6 +540,7 @@ 31.145 ["The draft of this initiative has been updated!"] = "Der Entwurfstext der Initiative wurde aktualisiert!"; 31.146 ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht"; 31.147 ["The initiators suggest to support the following initiative:"] = "Die Initiatoren empfehlen folgende Initiative zu unterstützen:"; 31.148 +["The interested members are updated after some time."] = false; 31.149 ["There are no more alternative initiatives currently."] = "Es gibt zur Zeit keine weiteren alternative Initiative."; 31.150 ["There were no more alternative initiatives."] = "Es gab keine weiteren alternativen Initiativen."; 31.151 ["This email address is too short!"] = "Diese E-Mail-Adresse ist zu kurz!"; 31.152 @@ -530,6 +556,8 @@ 31.153 ["This issue has been finished without any winning initiative."] = "Das Thema wurde ohne Gewinner abgeschlossen."; 31.154 ["This issue is already closed."] = "Das Thema ist schon geschlossen."; 31.155 ["This issue is already frozen."] = "Das Thema ist schon eingefroren"; 31.156 +["This issue is closed"] = "Thema geschlossen"; 31.157 +["This issue is in voting"] = "Thema in Abstimmung"; 31.158 ["This login is already taken, please choose another one!"] = "Dieser Anmeldename ist bereits vergeben, bitte wähle einen anderen!"; 31.159 ["This login is too short!"] = "Dieser Anmeldename ist zu kurz!"; 31.160 ["This member account has been created at #{created}"] = "Dieser Mitgliedszugang wurde am/um #{created} angelegt."; 31.161 @@ -570,6 +598,7 @@ 31.162 ["Voted no"] = "Mit Nein gestimmt"; 31.163 ["Voted proposal"] = "Abgestimmte Vorlage"; 31.164 ["Voted yes"] = "Mit Ja gestimmt"; 31.165 +["Votes"] = "Stimmzettel"; 31.166 ["Voting"] = "Abstimmung"; 31.167 ["Voting details"] = "Abstimmdetails"; 31.168 ["Voting for this issue has already begun."] = "Die Abstimmung für dieses Thema hat schon begonnen."; 31.169 @@ -591,9 +620,12 @@ 31.170 ["You are currently not invited to any initiative."] = "Du bist zur Zeit von keiner Initiative eingeladen."; 31.171 ["You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."] = "Du bist zur Zeit kein direkter Unterstützer dieser Initiative. Wenn Du eine Anregung hinzufügst wirst Du automatisch potentieller Unterstützer!"; 31.172 ["You are iniator of this initiative"] = "Du bist Initiator dieser Initiative"; 31.173 -["You are interested in this issue"] = "Du bist an diesem Thema interessiert"; 31.174 +["You are interested in this issue"] = "Du bist am Thema interessiert"; 31.175 +["You are interested in this issue by delegation"] = "Du bist am Thema durch Delegation interessiert"; 31.176 ["You are invited to become initiator of this initiative."] = "Du bist eingeladen Initiator dieser Initiative zu werden."; 31.177 ["You are member"] = "Du bist Mitglied"; 31.178 +["You are member of this area"] = "Du bist Mitglied des Themenbereichs"; 31.179 +["You are not interested in this issue"] = "Du bist nicht am Thema interessiert"; 31.180 ["You are now initiator of this initiative"] = "Du bist jetzt Initiator dieser Initiative"; 31.181 ["You are potential supporter of this initiative"] = "Du bist potentieller Unterstützer dieser Initiative"; 31.182 ["You are supporting this initiative"] = "Du unterstützt diese Initiative"; 31.183 @@ -603,11 +635,16 @@ 31.184 ["You didn't confirmed your email address '#{email}' within 7 days."] = "Du hast die E-Mail-Adresse '#{email}' nicht innerhalb von 7 Tagen bestätigt."; 31.185 ["You didn't confirmed your email address '#{email}'. You have received an email with an activation link."] = "Du hast die E-Mail-Adresse '#{email}' nicht bestätigt. Du hast hierzu eine E-Mail mit einem Aktivierungslink erhalten."; 31.186 ["You didn't saved any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!"; 31.187 +["You have delegated globally"] = "Du hast global delegiert"; 31.188 +["You have delegated this area"] = "Du hast das Themengebiet delegiert"; 31.189 +["You have delegated this issue"] = "Du hast das Thema delegiert"; 31.190 ["You have saved this member as contact"] = "Du hast das Mitglied als Kontakt gespeichert"; 31.191 ["You have saved this member as contact."] = "Du hast das Mitglied als Kontakt gespeichert."; 31.192 ["You have to mark 'Are you sure' to revoke!"] = "Zum Zurückziehen musst Du 'Sicher?' auswählen"; 31.193 ["You need to be logged in, to use all features of this system."] = "Du musst eingeloggt sein, um alle Funktionen dieses Systems nutzen zu können."; 31.194 ["You want to vote later"] = "Du willst später abstimmen"; 31.195 +["You were interested in this issue"] = "Du warst am Thema interessiert"; 31.196 +["You were interested in this issue by delegation"] = "Du warst am Thema durch Delegation interessiert"; 31.197 ["You've successfully registered and you can login now with your login and password!"] = "Du hast Dich erfolgreich registriert und kannst Dich jetzt mit Deinen Benutzernamen und Kennwort anmelden!"; 31.198 ["Your API key:"] = "Dein API-Schlüssel:"; 31.199 ["Your are interested"] = "Du bist interessiert"; 31.200 @@ -636,13 +673,25 @@ 31.201 ["Your vote has been discarded. Delegation rules apply if set."] = "Deine Abstimmung wurde zurückgezogen. Delegationsregeln gelten sofern gesetzt."; 31.202 ["Your web browser is not fully supported yet."] = "Dein Web-Browser wird noch nicht vollständig unterstützt."; 31.203 ["Z-A"] = "Z-A"; 31.204 +["[Change] or [revoke] area delegation [change]"] = false; 31.205 +["[Change] or [revoke] area delegation [midpart]"] = false; 31.206 +["[Change] or [revoke] area delegation [prefix]"] = false; 31.207 +["[Change] or [revoke] area delegation [revoke]"] = false; 31.208 +["[Change] or [revoke] area delegation [suffix]"] = false; 31.209 +["[Change] or [revoke] global delegation [change]"] = false; 31.210 +["[Change] or [revoke] global delegation [midpart]"] = false; 31.211 +["[Change] or [revoke] global delegation [prefix]"] = false; 31.212 +["[Change] or [revoke] global delegation [revoke]"] = false; 31.213 +["[Change] or [revoke] global delegation [suffix]"] = false; 31.214 ["[Registered members only]"] = "[nur für Registrierte]"; 31.215 ["[not displayed public]"] = "[nicht öffentlich]"; 31.216 ["a bit unsatisfied"] = "etwas unzufrieden"; 31.217 ["abandoned"] = "ausgesetzt"; 31.218 ["activated"] = "aktiviert"; 31.219 +["and"] = "und"; 31.220 ["and #{count} more initiatives"] = "und #{count} weitere Initiativen"; 31.221 ["area"] = "Themengebiet"; 31.222 +["by"] = "von"; 31.223 ["deactivated"] = "deaktiviert"; 31.224 ["delete<br /><br />"] = "löschen<br /><br />"; 31.225 ["disabled"] = "ausgeschaltet"; 31.226 @@ -658,12 +707,13 @@ 31.227 ["must/should not"] = "muss/soll nicht"; 31.228 ["neutral"] = "neutral"; 31.229 ["not implemented"] = "nicht umgesetzt"; 31.230 +["not yet"] = false; 31.231 ["requested"] = "angefragt"; 31.232 ["satisfied"] = "zufrieden"; 31.233 ["should"] = "soll"; 31.234 ["should not"] = "soll nicht"; 31.235 +["since #{date}"] = "seit #{date}"; 31.236 ["to reset your password please click on the following link:\n\n"] = "um Dein Kennwort zurückzusetzen klicke bitte den folgenden Link an:\n\n"; 31.237 ["until"] = "bis"; 31.238 ["xmpp"] = "Jabber (XMPP)"; 31.239 -["Last login (updated daily)"] = "Letzte Anmeldung (täglich aktualisiert)"; 31.240 }
32.1 --- a/locale/translations.en.lua Sat Feb 05 20:01:09 2011 +0100 32.2 +++ b/locale/translations.en.lua Wed Mar 02 20:06:26 2011 +0100 32.3 @@ -3,14 +3,20 @@ 32.4 ["##{id}"] = false; 32.5 ["##{issue_id}.#{id} #{name}"] = false; 32.6 ["#{author} at #{date}"] = false; 32.7 +["#{direct_count}+#{delegated_count} Mitglieder"] = false; 32.8 ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = false; 32.9 ["#{issues_to_vote_count} issue(s)"] = false; 32.10 ["#{number} Image(s) has been deleted"] = false; 32.11 ["#{number} Image(s) has been updated"] = false; 32.12 +["#{suggestion_count} suggestions"] = false; 32.13 +["#{supporter_count} supporters"] = false; 32.14 +["#{time_left} left"] = false; 32.15 +["#{vote_count} votes"] = false; 32.16 ["(#{more_count} duplicates removed)"] = false; 32.17 ["(change URL)"] = false; 32.18 ["(new window)"] = false; 32.19 ["+ #{weight}"] = false; 32.20 +["+getElementById("] = false; 32.21 ["A-Z"] = false; 32.22 ["API key"] = false; 32.23 ["API key has been deleted"] = false; 32.24 @@ -62,6 +68,8 @@ 32.25 ["Area list"] = false; 32.26 ["Area successfully updated"] = false; 32.27 ["Areas"] = false; 32.28 +["Areas, you are member of"] = false; 32.29 +["Areas, you are not member of"] = false; 32.30 ["Author"] = false; 32.31 ["Auto support is now disabled"] = false; 32.32 ["Auto support is now enabled"] = false; 32.33 @@ -77,6 +85,7 @@ 32.34 ["Back to timeline"] = false; 32.35 ["Ballot of '#{member_name}' for issue ##{issue_id}"] = false; 32.36 ["Become a member"] = false; 32.37 +["Become a member of this area"] = false; 32.38 ["Birthday"] = false; 32.39 ["Can't remove last initiator"] = false; 32.40 ["Can't send confirmation email"] = false; 32.41 @@ -87,6 +96,7 @@ 32.42 ["Cancelled"] = false; 32.43 ["Change API key"] = false; 32.44 ["Change area delegation"] = false; 32.45 +["Change delegation..."] = false; 32.46 ["Change display settings"] = false; 32.47 ["Change email"] = false; 32.48 ["Change email address"] = false; 32.49 @@ -106,9 +116,11 @@ 32.50 ["Choose member"] = false; 32.51 ["Click for details"] = false; 32.52 ["Closed"] = false; 32.53 +["Closed since #{date}"] = false; 32.54 ["Collective opinion of supporters"] = false; 32.55 ["Commit suggestion"] = false; 32.56 ["Compare"] = false; 32.57 +["Compare selected"] = false; 32.58 ["Confirm"] = false; 32.59 ["Confirmation code"] = false; 32.60 ["Confirmation code invalid!"] = false; 32.61 @@ -116,9 +128,12 @@ 32.62 ["Contacts"] = false; 32.63 ["Content"] = false; 32.64 ["Counting of votes"] = false; 32.65 +["Create / edit area"] = false; 32.66 +["Create / edit policy"] = false; 32.67 ["Create alternative initiative"] = false; 32.68 ["Create new area"] = false; 32.69 ["Create new issue"] = false; 32.70 +["Create new policy"] = false; 32.71 ["Created at"] = false; 32.72 ["Current draft"] = false; 32.73 ["Current name"] = false; 32.74 @@ -130,6 +145,8 @@ 32.75 ["Date format is not valid. Please use following format: YYYY-MM-DD"] = false; 32.76 ["Default Policy"] = false; 32.77 ["Degree"] = false; 32.78 +["Delegate area..."] = false; 32.79 +["Delegate issue"] = false; 32.80 ["Delegation abandoned"] = false; 32.81 ["Delegation problems"] = false; 32.82 ["Delegation turned off for area"] = false; 32.83 @@ -163,6 +180,7 @@ 32.84 ["Download database export"] = false; 32.85 ["Draft"] = false; 32.86 ["Draft history"] = false; 32.87 +["Draft revisions"] = false; 32.88 ["EXPERIMENTAL FEATURE"] = false; 32.89 ["Edit"] = false; 32.90 ["Edit draft"] = false; 32.91 @@ -190,6 +208,7 @@ 32.92 ["Fully frozen at"] = false; 32.93 ["Generate / change API key"] = false; 32.94 ["Generate API key"] = false; 32.95 +["Give up membership"] = false; 32.96 ["Global delegation"] = false; 32.97 ["Global delegation active"] = false; 32.98 ["Go up"] = false; 32.99 @@ -200,6 +219,7 @@ 32.100 ["Hide"] = false; 32.101 ["Hide filter details"] = false; 32.102 ["Hide this help message"] = false; 32.103 +["Hint"] = false; 32.104 ["History"] = false; 32.105 ["Home"] = false; 32.106 ["I consider suggestion as"] = false; 32.107 @@ -210,6 +230,7 @@ 32.108 ["Images"] = false; 32.109 ["In discussion"] = false; 32.110 ["Incoming delegations"] = false; 32.111 +["Index"] = false; 32.112 ["Information about the available policies"] = false; 32.113 ["Inherit autoreject from area"] = false; 32.114 ["Initiated"] = false; 32.115 @@ -217,7 +238,11 @@ 32.116 ["Initiative ##{id}"] = false; 32.117 ["Initiative events"] = false; 32.118 ["Initiative is revoked now"] = false; 32.119 +["Initiative not admitted"] = false; 32.120 +["Initiative not agreed"] = false; 32.121 ["Initiative quorum"] = false; 32.122 +["Initiative quorum denumerator"] = false; 32.123 +["Initiative quorum numerator"] = false; 32.124 ["Initiative revoked"] = false; 32.125 ["Initiative successfully created"] = false; 32.126 ["Initiative successfully updated"] = false; 32.127 @@ -232,12 +257,14 @@ 32.128 ["Initiator"] = false; 32.129 ["Initiator invites"] = false; 32.130 ["Initiators"] = false; 32.131 +["Interest"] = false; 32.132 ["Interest not existant"] = false; 32.133 ["Interest removed"] = false; 32.134 ["Interest updated"] = false; 32.135 ["Interested"] = false; 32.136 ["Interested members"] = false; 32.137 ["Internal posts"] = false; 32.138 +["Interval format:"] = false; 32.139 ["Invalid query"] = false; 32.140 ["Invalid username or password!"] = false; 32.141 ["Invitation has been refused"] = false; 32.142 @@ -255,11 +282,16 @@ 32.143 ["Issue finished"] = false; 32.144 ["Issue finished without voting"] = false; 32.145 ["Issue frozen"] = false; 32.146 +["Issue not accepted"] = false; 32.147 ["Issue policy"] = false; 32.148 ["Issue quorum"] = false; 32.149 +["Issue quorum denumerator"] = false; 32.150 +["Issue quorum numerator"] = false; 32.151 ["Issues"] = false; 32.152 ["JavaScript is disabled or not available."] = false; 32.153 ["Last author"] = false; 32.154 +["Last change"] = false; 32.155 +["Last login (updated daily)"] = false; 32.156 ["Last snapshot:"] = false; 32.157 ["Legend:"] = false; 32.158 ["License"] = false; 32.159 @@ -270,6 +302,8 @@ 32.160 ["Logout"] = false; 32.161 ["Logout successful"] = false; 32.162 ["Majority"] = false; 32.163 +["Majority denumerator"] = false; 32.164 +["Majority numerator"] = false; 32.165 ["Manage filter"] = false; 32.166 ["Manage timeline filters"] = false; 32.167 ["Max potential support"] = false; 32.168 @@ -324,6 +358,7 @@ 32.169 ["No changes to your images were made"] = false; 32.170 ["No default"] = false; 32.171 ["No delegation"] = false; 32.172 +["No delegation active"] = false; 32.173 ["No events selected to list"] = false; 32.174 ["No membership at all"] = false; 32.175 ["No support at all"] = false; 32.176 @@ -380,6 +415,8 @@ 32.177 ["Policies"] = false; 32.178 ["Policy"] = false; 32.179 ["Policy '#{name}'"] = false; 32.180 +["Policy list"] = false; 32.181 +["Policy successfully updated"] = false; 32.182 ["Population"] = false; 32.183 ["Posts"] = false; 32.184 ["Potential support"] = false; 32.185 @@ -428,6 +465,7 @@ 32.186 ["Saved as contact"] = false; 32.187 ["Saved contacts"] = false; 32.188 ["Search"] = false; 32.189 +["Search in initiatives for text:"] = false; 32.190 ["Search initiatives"] = false; 32.191 ["Search issues"] = false; 32.192 ["Search members"] = false; 32.193 @@ -456,6 +494,8 @@ 32.194 ["Show member"] = false; 32.195 ["Show name history"] = false; 32.196 ["Show only events which match... (or associtated)"] = false; 32.197 +["Show policies in use"] = false; 32.198 +["Show policies not in use"] = false; 32.199 ["So I'm"] = false; 32.200 ["Software"] = false; 32.201 ["Some JavaScript based functions (voting in particular) will not work.\nFor this beta, please use a current version of Firefox, Safari, Opera(?), Konqueror or another (more) standard compliant browser.\nAlternative access without JavaScript will be available soon."] = false; 32.202 @@ -473,6 +513,7 @@ 32.203 ["Step 3/5: Username"] = false; 32.204 ["Step 4/5: Login name"] = false; 32.205 ["Step 5/5: Terms of use and password"] = false; 32.206 +["Strict majority"] = false; 32.207 ["Stylesheet URL"] = false; 32.208 ["Stylesheet URL has been updated"] = false; 32.209 ["Suggest no initiative"] = false; 32.210 @@ -490,6 +531,7 @@ 32.211 ["Supported"] = false; 32.212 ["Supported initiatives"] = false; 32.213 ["Supporter"] = false; 32.214 +["Supporters"] = false; 32.215 ["Syntax help"] = false; 32.216 ["Tabs"] = false; 32.217 ["Terms of use"] = false; 32.218 @@ -498,6 +540,7 @@ 32.219 ["The draft of this initiative has been updated!"] = false; 32.220 ["The drafts do not differ"] = false; 32.221 ["The initiators suggest to support the following initiative:"] = false; 32.222 +["The interested members are updated after some time."] = false; 32.223 ["There are no more alternative initiatives currently."] = false; 32.224 ["There were no more alternative initiatives."] = false; 32.225 ["This email address is too short!"] = false; 32.226 @@ -513,6 +556,8 @@ 32.227 ["This issue has been finished without any winning initiative."] = false; 32.228 ["This issue is already closed."] = false; 32.229 ["This issue is already frozen."] = false; 32.230 +["This issue is closed"] = false; 32.231 +["This issue is in voting"] = false; 32.232 ["This login is already taken, please choose another one!"] = false; 32.233 ["This login is too short!"] = false; 32.234 ["This member account has been created at #{created}"] = false; 32.235 @@ -553,6 +598,7 @@ 32.236 ["Voted no"] = false; 32.237 ["Voted proposal"] = false; 32.238 ["Voted yes"] = false; 32.239 +["Votes"] = false; 32.240 ["Voting"] = false; 32.241 ["Voting details"] = false; 32.242 ["Voting for this issue has already begun."] = false; 32.243 @@ -575,8 +621,11 @@ 32.244 ["You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."] = false; 32.245 ["You are iniator of this initiative"] = false; 32.246 ["You are interested in this issue"] = false; 32.247 +["You are interested in this issue by delegation"] = false; 32.248 ["You are invited to become initiator of this initiative."] = false; 32.249 ["You are member"] = false; 32.250 +["You are member of this area"] = false; 32.251 +["You are not interested in this issue"] = false; 32.252 ["You are now initiator of this initiative"] = false; 32.253 ["You are potential supporter of this initiative"] = false; 32.254 ["You are supporting this initiative"] = false; 32.255 @@ -586,11 +635,16 @@ 32.256 ["You didn't confirmed your email address '#{email}' within 7 days."] = false; 32.257 ["You didn't confirmed your email address '#{email}'. You have received an email with an activation link."] = false; 32.258 ["You didn't saved any member as contact yet."] = false; 32.259 +["You have delegated globally"] = false; 32.260 +["You have delegated this area"] = false; 32.261 +["You have delegated this issue"] = false; 32.262 ["You have saved this member as contact"] = false; 32.263 ["You have saved this member as contact."] = false; 32.264 ["You have to mark 'Are you sure' to revoke!"] = false; 32.265 ["You need to be logged in, to use all features of this system."] = false; 32.266 ["You want to vote later"] = false; 32.267 +["You were interested in this issue"] = false; 32.268 +["You were interested in this issue by delegation"] = false; 32.269 ["You've successfully registered and you can login now with your login and password!"] = false; 32.270 ["Your API key:"] = false; 32.271 ["Your are interested"] = false; 32.272 @@ -619,13 +673,25 @@ 32.273 ["Your vote has been discarded. Delegation rules apply if set."] = false; 32.274 ["Your web browser is not fully supported yet."] = false; 32.275 ["Z-A"] = false; 32.276 +["[Change] or [revoke] area delegation [change]"] = "Change"; 32.277 +["[Change] or [revoke] area delegation [midpart]"] = " or "; 32.278 +["[Change] or [revoke] area delegation [prefix]"] = ""; 32.279 +["[Change] or [revoke] area delegation [revoke]"] = "revoke"; 32.280 +["[Change] or [revoke] area delegation [suffix]"] = " area delegation"; 32.281 +["[Change] or [revoke] global delegation [change]"] = "Change"; 32.282 +["[Change] or [revoke] global delegation [midpart]"] = " or "; 32.283 +["[Change] or [revoke] global delegation [prefix]"] = ""; 32.284 +["[Change] or [revoke] global delegation [revoke]"] = "revoke"; 32.285 +["[Change] or [revoke] global delegation [suffix]"] = " global delegation"; 32.286 ["[Registered members only]"] = false; 32.287 ["[not displayed public]"] = false; 32.288 ["a bit unsatisfied"] = false; 32.289 ["abandoned"] = false; 32.290 ["activated"] = false; 32.291 +["and"] = false; 32.292 ["and #{count} more initiatives"] = false; 32.293 ["area"] = false; 32.294 +["by"] = false; 32.295 ["deactivated"] = false; 32.296 ["delete<br /><br />"] = false; 32.297 ["disabled"] = false; 32.298 @@ -641,10 +707,12 @@ 32.299 ["must/should not"] = false; 32.300 ["neutral"] = false; 32.301 ["not implemented"] = false; 32.302 +["not yet"] = false; 32.303 ["requested"] = false; 32.304 ["satisfied"] = false; 32.305 ["should"] = false; 32.306 ["should not"] = false; 32.307 +["since #{date}"] = false; 32.308 ["to reset your password please click on the following link:\n\n"] = false; 32.309 ["until"] = false; 32.310 ["xmpp"] = false;
33.1 --- a/model/area.lua Sat Feb 05 20:01:09 2011 +0100 33.2 +++ b/model/area.lua Wed Mar 02 20:06:26 2011 +0100 33.3 @@ -63,5 +63,12 @@ 33.4 if args.active ~= nil then 33.5 selector:add_where{ "active = ?", args.active } 33.6 end 33.7 + if args.member_id then 33.8 + selector:join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ?", args.member_id }) 33.9 + end 33.10 + if args.not_member_id then 33.11 + selector:left_join("membership", nil, { "membership.area_id = area.id AND membership.member_id = ?", args.not_member_id }) 33.12 + selector:add_where{ "membership.member_id ISNULL" } 33.13 + end 33.14 return selector 33.15 end
34.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 34.2 +++ b/model/delegating_interest_snapshot.lua Wed Mar 02 20:06:26 2011 +0100 34.3 @@ -0,0 +1,10 @@ 34.4 +DelegatingInterestSnapshot = mondelefant.new_class() 34.5 +DelegatingInterestSnapshot.table = 'delegating_interest_snapshot' 34.6 +DelegatingInterestSnapshot.primary_key = { "issue_id", "event", "member_id" } 34.7 + 34.8 +function DelegatingInterestSnapshot:by_pk(issue_id, event, member_id) 34.9 + return self:new_selector() 34.10 + :add_where{ "issue_id = ? AND event = ? AND member_id = ?", issue_id, event, member_id } 34.11 + :optional_object_mode() 34.12 + :exec() 34.13 +end 34.14 \ No newline at end of file
35.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 35.2 +++ b/model/direct_interest_snapshot.lua Wed Mar 02 20:06:26 2011 +0100 35.3 @@ -0,0 +1,10 @@ 35.4 +DirectInterestSnapshot = mondelefant.new_class() 35.5 +DirectInterestSnapshot.table = 'direct_interest_snapshot' 35.6 +DirectInterestSnapshot.primary_key = { "issue_id", "event", "member_id" } 35.7 + 35.8 +function DirectInterestSnapshot:by_pk(issue_id, event, member_id) 35.9 + return self:new_selector() 35.10 + :add_where{ "issue_id = ? AND event = ? AND member_id = ?", issue_id, event, member_id } 35.11 + :optional_object_mode() 35.12 + :exec() 35.13 +end 35.14 \ No newline at end of file
36.1 --- a/model/issue.lua Sat Feb 05 20:01:09 2011 +0100 36.2 +++ b/model/issue.lua Wed Mar 02 20:06:26 2011 +0100 36.3 @@ -23,7 +23,8 @@ 36.4 this_key = 'id', 36.5 that_key = 'issue_id', 36.6 ref = 'initiatives', 36.7 - back_ref = 'issue' 36.8 + back_ref = 'issue', 36.9 + default_order = 'initiative.rank, initiative.admitted ISNULL, initiative.admitted DESC, initiative.positive_votes::float / initiative.negative_votes::float DESC, initiative.supporter_count DESC' 36.10 } 36.11 36.12 Issue:add_reference{ 36.13 @@ -85,7 +86,7 @@ 36.14 connected_by_that_key = 'member_id', 36.15 ref = 'members' 36.16 } 36.17 - 36.18 +--[[ 36.19 Issue:add_reference{ 36.20 mode = 'mm', 36.21 to = "Member", 36.22 @@ -96,7 +97,7 @@ 36.23 connected_by_that_key = 'member_id', 36.24 ref = 'interested_members_snapshot' 36.25 } 36.26 - 36.27 +--]] 36.28 Issue:add_reference{ 36.29 mode = 'mm', 36.30 to = "Member", 36.31 @@ -108,6 +109,133 @@ 36.32 ref = 'direct_voters' 36.33 } 36.34 36.35 +Issue:add_reference{ 36.36 + mode = 'mm', 36.37 + to = "Member", 36.38 + this_key = 'id', 36.39 + that_key = 'id', 36.40 + connected_by_table = 'direct_interest_snapshot', 36.41 + connected_by_this_key = 'issue_id', 36.42 + connected_by_that_key = 'member_id', 36.43 + ref = 'interested_members_snapshot', 36.44 + selector_generator = function(list, options) 36.45 + -- build list of issue ids 36.46 + local ids = { sep = ", " } 36.47 + for i, object in ipairs(list) do 36.48 + local id = object.id 36.49 + if id ~= nil then 36.50 + ids[#ids+1] = {"?", id} 36.51 + end 36.52 + end 36.53 + 36.54 + if #ids == 0 then 36.55 + return Member:new_selector():empty_list_mode() 36.56 + end 36.57 + 36.58 + local selector = Member:new_selector() 36.59 + selector:join("direct_interest_snapshot", nil, { "direct_interest_snapshot.member_id = member.id AND direct_interest_snapshot.issue_id IN ($)", ids }) 36.60 + selector:join("issue", nil, "direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.event = issue.latest_snapshot_event") 36.61 + selector:add_order_by('direct_interest_snapshot.weight DESC') 36.62 + return selector 36.63 + end 36.64 +} 36.65 + 36.66 +Issue:add_reference{ 36.67 + mode = '11', 36.68 + to = "DelegatingInterestSnapshot", 36.69 + this_key = 'id', 36.70 + that_key = 'issue_id', 36.71 + ref = 'delegating_interest_snapshot_for_member', 36.72 + back_ref = 'issue', 36.73 + selector_generator = function(list, options) 36.74 + local member_id = assert(options.member_id) 36.75 + 36.76 + -- build list of issue ids 36.77 + local ids = { sep = ", " } 36.78 + for i, object in ipairs(list) do 36.79 + local id = object.id 36.80 + if id ~= nil then 36.81 + ids[#ids+1] = {"?", id} 36.82 + end 36.83 + end 36.84 + 36.85 + if #ids == 0 then 36.86 + return DelegatingInterestSnapshot:new_selector():empty_list_mode() 36.87 + end 36.88 + 36.89 + local selector = DelegatingInterestSnapshot:new_selector() 36.90 + selector:join("issue", nil, "delegating_interest_snapshot.issue_id = issue.id AND delegating_interest_snapshot.event = issue.latest_snapshot_event") 36.91 + selector:add_where{ 'delegating_interest_snapshot.issue_id IN ($)', ids } 36.92 + selector:add_where{ 'delegating_interest_snapshot.member_id = ?', options.member_id } 36.93 + 36.94 + return selector 36.95 + end 36.96 +} 36.97 + 36.98 +Issue:add_reference{ 36.99 + mode = '11', 36.100 + to = "Interest", 36.101 + this_key = 'id', 36.102 + that_key = 'issue_id', 36.103 + ref = 'interest_for_member', 36.104 + back_ref = 'issue', 36.105 + selector_generator = function(list, options) 36.106 + 36.107 + local member_id = assert(options.member_id) 36.108 + 36.109 + -- build list of issue ids 36.110 + local ids = { sep = ", " } 36.111 + for i, object in ipairs(list) do 36.112 + local id = object.id 36.113 + if id ~= nil then 36.114 + ids[#ids+1] = {"?", id} 36.115 + end 36.116 + end 36.117 + 36.118 + if #ids == 0 then 36.119 + return Interest:new_selector():empty_list_mode() 36.120 + end 36.121 + 36.122 + local selector = Interest:new_selector() 36.123 + selector:add_where{ 'interest.issue_id IN ($)', ids } 36.124 + selector:add_where{ 'interest.member_id = ?', member_id } 36.125 + return selector 36.126 + 36.127 + end 36.128 +} 36.129 + 36.130 +Issue:add_reference{ 36.131 + mode = '1m', 36.132 + to = "Delegation", 36.133 + this_key = 'id', 36.134 + that_key = 'issue_id', 36.135 + ref = 'outgoing_delegations_for_member', 36.136 + back_ref = 'issue', 36.137 + selector_generator = function(list, options) 36.138 + 36.139 + local member_id = assert(options.member_id) 36.140 + 36.141 + -- build list of issue ids 36.142 + local ids = { sep = ", " } 36.143 + for i, object in ipairs(list) do 36.144 + local id = object.id 36.145 + if id ~= nil then 36.146 + ids[#ids+1] = {"?", id} 36.147 + end 36.148 + end 36.149 + 36.150 + if #ids == 0 then 36.151 + return Delegation:new_selector():empty_list_mode() 36.152 + end 36.153 + 36.154 + local selector = Delegation:new_selector() 36.155 + selector:add_where{ 'delegation.issue_id IN ($)', ids } 36.156 + selector:add_where{ 'delegation.truster_id = ?', member_id } 36.157 + return selector 36.158 + 36.159 + end 36.160 +} 36.161 + 36.162 36.163 36.164 function Issue:get_state_name_for_state(value) 36.165 @@ -169,6 +297,33 @@ 36.166 end 36.167 end 36.168 36.169 +function Issue:build_selector(args) 36.170 + local selector = self:new_selector() 36.171 + if args.area_id then 36.172 + selector:add_where{ "issue.area_id = ?", args.area_id } 36.173 + end 36.174 + if args.state == "closed" then 36.175 + selector:add_where("issue.closed NOTNULL") 36.176 + elseif args.state == "voting" then 36.177 + selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") 36.178 + elseif args.state == "frozen" then 36.179 + selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL AND issue.closed ISNULL") 36.180 + elseif args.state == "discussion" then 36.181 + selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") 36.182 + elseif args.state == "new" then 36.183 + selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") 36.184 + end 36.185 + if args.order == "time_left" then 36.186 + selector:add_order_by("issue.closed DESC") 36.187 + elseif args.order == "last_change" then 36.188 + selector:add_order_by("issue.closed DESC") 36.189 + elseif args.order == "interest" then 36.190 + selector:add_order_by("issue.population DESC") 36.191 + end 36.192 + 36.193 + return selector 36.194 +end 36.195 + 36.196 function Issue.object_get:state() 36.197 if self.closed then 36.198 if self.fully_frozen then
37.1 Binary file static/lf2/icon_award_gold.png has changed
38.1 Binary file static/lf2/icon_award_silver.png has changed
39.1 Binary file static/lf2/icon_cross.png has changed
40.1 Binary file static/lf2/icon_delegated_star.png has changed
41.1 Binary file static/lf2/icon_delegation.png has changed
42.1 Binary file static/lf2/icon_delegation_area.png has changed
43.1 Binary file static/lf2/icon_delegation_global.png has changed
44.1 Binary file static/lf2/icon_eye.png has changed
45.1 Binary file static/lf2/icon_search.png has changed
46.1 Binary file static/lf2/icon_search_crossed.png has changed
47.1 Binary file static/lf2/icon_star.png has changed
48.1 Binary file static/lf2/icon_star_crossed.png has changed
49.1 Binary file static/lf2/icon_star_grey.png has changed
50.1 Binary file static/lf2/icon_suggestion.png has changed
51.1 Binary file static/lf2/icon_supporter.png has changed
52.1 Binary file static/lf2/icon_text.png has changed
53.1 Binary file static/lf2/icon_vote.png has changed