# HG changeset patch # User bsw/jbe # Date 1260442800 -3600 # Node ID 80c215dbf076ef6430db88047372e57893dba2a3 # Parent 768faea1096db7ad6f07873029c59069ce4b256d Version alpha5 Many optical changes and improved usability Support for different wiki-formatting-engines Help system diff -r 768faea1096d -r 80c215dbf076 app/main/_filter_view/30_navigation.lua --- a/app/main/_filter_view/30_navigation.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/_filter_view/30_navigation.lua Thu Dec 10 12:00:00 2009 +0100 @@ -71,6 +71,15 @@ view = 'about' } + ui.link{ + content = function() + ui.image{ static = "icons/16/bug.png" } + slot.put(_'Bug report') + end, + external = "http://trac.public-software-group.org/projects/lf" --/newticket?description=" .. encode.url_part("\n\n\n\nReport for: " .. os.getenv("REQUEST_URI") ) + } + + if app.session.member.admin then slot.put(" ") @@ -89,6 +98,12 @@ end) +if config.app_logo then + slot.select("logo", function() + ui.image{ static = config.app_logo } + end) +end + execute.inner() diff -r 768faea1096d -r 80c215dbf076 app/main/_filter_view/33_help_hidden.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/_filter_view/33_help_hidden.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,36 @@ +execute.inner() + +if util._hidden_helps ~= nil then + slot.select("help_hidden", function() + for i, help in ipairs(util._hidden_helps) do + ui.link{ + attr = { + class = "help_hidden", + title = _("Help for: #{text}", { text = help.title }) + }, + module = "help", + action = "update", + params = { + help_ident = help.id, + hide = false + }, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + }, + content = function() + ui.image{ + attr = { class = "help_icon" }, + static = "icons/16/help.png" + } + end + } + end + end) +end + diff -r 768faea1096d -r 80c215dbf076 app/main/_layout/default.html --- a/app/main/_layout/default.html Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/_layout/default.html Thu Dec 10 12:00:00 2009 +0100 @@ -18,29 +18,47 @@ +
+ +
+
+ +
+
+ +
-
- -
-
- -
-
- +
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
-
- -
-
- -
-
- -
-
- -
-
@@ -55,15 +73,6 @@
-
- -
-
- -
-
- -
diff -r 768faea1096d -r 80c215dbf076 app/main/area/_action/update.lua --- a/app/main/area/_action/update.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/area/_action/update.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,3 +1,7 @@ +if not app.session.member.admin then + error() +end + local id = param.get_id() local area diff -r 768faea1096d -r 80c215dbf076 app/main/area/_list.lua --- a/app/main/area/_list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/area/_list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -35,7 +35,7 @@ local max_value = MemberCount:get() ui.bargraph{ max_value = max_value, - width = 200, + width = 100, bars = { { color = "#444", value = record.direct_member_count }, { color = "#777", value = record.member_weight - record.direct_member_count }, @@ -58,4 +58,14 @@ } } end -} \ No newline at end of file +} + +ui.bargraph_legend{ + width = 25, + bars = { + { color = "#444", label = _"Direct membership" }, + { color = "#777", label = _"Membership by delegation" }, + { color = "#ddd", label = _"No membership at all" }, + } +} + diff -r 768faea1096d -r 80c215dbf076 app/main/area/list.lua --- a/app/main/area/list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/area/list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,5 +1,7 @@ slot.put_into("title", _'Area list') +util.help("area.list", _"Area list") + local areas_selector = Area:new_selector():add_where("active") execute.view{ @@ -8,7 +10,9 @@ params = { areas_selector = areas_selector } } +--[[ execute.view{ module = "delegation", view = "_show_box" -} \ No newline at end of file +} +--]] diff -r 768faea1096d -r 80c215dbf076 app/main/area/show.lua --- a/app/main/area/show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/area/show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -13,15 +13,6 @@ slot.select("actions", function() ui.link{ content = function() - ui.image{ static = "icons/16/table_go.png" } - slot.put(_"Delegate") - end, - module = "delegation", - view = "new", - params = { area_id = area.id } - } - ui.link{ - content = function() ui.image{ static = "icons/16/folder_add.png" } slot.put(_"Create new issue") end, @@ -31,6 +22,8 @@ } end) +util.help("area.show") + execute.view{ module = "membership", view = "_show_box", diff -r 768faea1096d -r 80c215dbf076 app/main/contact/_list.lua --- a/app/main/contact/_list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/contact/_list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -2,7 +2,7 @@ local contacts_selector = Contact:new_selector() :add_where{ "member_id = ?", app.session.member.id } :join("member", nil, "member.id = contact.other_member_id") - :add_order_by("member.login") + :add_order_by("member.name") ui.paginate{ selector = contacts_selector, @@ -15,17 +15,6 @@ records = contacts, columns = { { - label = _"Login", - content = function(record) - ui.link{ - text = record.other_member.login, - module = "member", - view = "show", - id = record.other_member_id - } - end - }, - { label = _"Name", content = function(record) ui.link{ @@ -103,30 +92,8 @@ } end }, - { - content = function(record) - ui.link{ - attr = { class = "action" }, - text = _"Global delegation", - module = "delegation", - action = "update", - params = { - trustee_id = record.other_member_id, - }, - routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } - } - end - } } } end end -} \ No newline at end of file +} diff -r 768faea1096d -r 80c215dbf076 app/main/contact/list.lua --- a/app/main/contact/list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/contact/list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,5 +1,7 @@ slot.put_into("title", _"Contacts") +util.help("contact.list") + execute.view{ module = "contact", view = "_list", diff -r 768faea1096d -r 80c215dbf076 app/main/delegation/_action/update.lua --- a/app/main/delegation/_action/update.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/delegation/_action/update.lua Thu Dec 10 12:00:00 2009 +0100 @@ -12,7 +12,7 @@ local delegation = Delegation:by_pk(truster_id, area_id, issue_id) -if param.get("delete") then +if param.get("delete") or trustee_id == -1 then if delegation then diff -r 768faea1096d -r 80c215dbf076 app/main/delegation/_show_box.lua --- a/app/main/delegation/_show_box.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/delegation/_show_box.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,121 +1,192 @@ -slot.select("delegation", function() - - local delegation - local area_id - local issue_id - - local scope = "global" - - if param.get("initiative_id", atom.integer) then - issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id - scope = "issue" - end - - if param.get("issue_id", atom.integer) then - issue_id = param.get("issue_id", atom.integer) - scope = "issue" - end - - if param.get("area_id", atom.integer) then - area_id = param.get("area_id", atom.integer) - scope = "area" - end - - +slot.select("actions", function() - local delegation - - if issue_id then - delegation = Delegation:by_pk(app.session.member.id, nil, issue_id) - if not delegation then - local issue = Issue:by_id(issue_id) - delegation = Delegation:by_pk(app.session.member.id, issue.area_id) - end - elseif area_id then - delegation = Delegation:by_pk(app.session.member.id, area_id) - end - - if not delegation then - delegation = Delegation:by_pk(app.session.member.id) - end - if delegation then - ui.container{ - attr = { - class = "head", - style = "cursor: pointer;", - onclick = "document.getElementById('delegation_content').style.display = 'block';" - }, - content = _"Your vote is delegated. [more]" - } - ui.container{ - attr = { class = "content", id = "delegation_content" }, - content = function() + ui.container{ + attr = { class = "delegation vote_info"}, + content = function() + + local delegation + local area_id + local issue_id + + local scope = "global" + + if param.get("initiative_id", atom.integer) then + issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id + scope = "issue" + end + + if param.get("issue_id", atom.integer) then + issue_id = param.get("issue_id", atom.integer) + scope = "issue" + end + + if param.get("area_id", atom.integer) then + area_id = param.get("area_id", atom.integer) + scope = "area" + end + + + + local delegation + + if issue_id then + delegation = Delegation:by_pk(app.session.member.id, nil, issue_id) + if not delegation then + local issue = Issue:by_id(issue_id) + delegation = Delegation:by_pk(app.session.member.id, issue.area_id) + end + elseif area_id then + delegation = Delegation:by_pk(app.session.member.id, area_id) + end + + if not delegation then + delegation = Delegation:by_pk(app.session.member.id) + end + if delegation then ui.container{ attr = { - class = "close", + title = _"Click for details", + class = "head head_active", style = "cursor: pointer;", - onclick = "document.getElementById('delegation_content').style.display = 'none';" + onclick = "document.getElementById('delegation_content').style.display = 'block';" }, - content = _"X" + content = function() + ui.image{ + static = "icons/16/error.png" + } + if delegation.issue_id then + slot.put(_"Issue delegation active") + elseif delegation.area_id then + slot.put(_"Area wide delegation active") + else + slot.put(_"Global delegation active") + end + ui.image{ + static = "icons/16/dropdown.png" + } + end } - - local delegation_chain = db:query{ "SELECT * FROM delegation_chain(?, ?, ?) JOIN member ON member.id = member_id ORDER BY index", app.session.member.id, area_id, issue_id } - - for i, record in ipairs(delegation_chain) do - local style - execute.view{ - module = "member", - view = "_show_thumb", - params = { member = record } - } - slot.put("
") - if record.scope_out then + ui.container{ + attr = { class = "content", id = "delegation_content" }, + content = function() ui.container{ - attr = { class = "delegation_info" }, + attr = { + class = "close", + style = "cursor: pointer;", + onclick = "document.getElementById('delegation_content').style.display = 'none';" + }, content = function() - ui.image{ - attr = { class = "delegation_arrow" }, - static = "delegation_arrow_vertical.jpg" - } + ui.image{ static = "icons/16/cross.png" } + end + } + + local delegation_chain = Member:new_selector() + :add_field("delegation_chain.*") + :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") + :add_order_by("index") + :exec() + + for i, record in ipairs(delegation_chain) do + local style + local overridden = record.overridden + if record.scope_in then ui.container{ - attr = { class = "delegation_scope" }, + attr = { class = "delegation_info" }, content = function() - if record.scope_out == "global" then - slot.put(_"Global delegation") - elseif record.scope_out == "area" then - slot.put(_"Area delegation") - elseif record.scope_out == "issue" then - slot.put(_"Issue delegation") + if not overridden then + ui.image{ + attr = { class = "delegation_arrow" }, + static = "delegation_arrow_vertical.jpg" + } + else + ui.image{ + attr = { class = "delegation_arrow delegation_arrow_overridden" }, + static = "delegation_arrow_vertical.jpg" + } + end + ui.container{ + attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") }, + content = function() + if record.scope_in == "global" then + slot.put(_"Global delegation") + elseif record.scope_in == "area" then + slot.put(_"Area delegation") + elseif record.scope_in == "issue" then + slot.put(_"Issue delegation") + end + end + } + if i == 2 then + ui.link{ + attr = { class = "revoke" }, + content = function() + ui.image{ static = "icons/16/delete.png" } + slot.put(_"Revoke") + end, + module = "delegation", + action = "update", + params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true }, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } + } end end } - if record.id == app.session.member.id then - ui.link{ - attr = { class = "revoke" }, - content = function() - ui.image{ static = "icons/16/delete.png" } - slot.put(_"Revoke") - end, - module = "delegation", - action = "update", - params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true }, - routing = { - default = { - mode = "redirect", - module = request.get_module(), - view = request.get_view(), - id = param.get_id_cgi(), - params = param.get_all_cgi() - } - } + end + ui.container{ + attr = { class = overridden and "delegation_overridden" or "" }, + content = function() + execute.view{ + module = "member", + view = "_show_thumb", + params = { member = record } } end + } + if record.participation and not record.overridden then + ui.container{ + attr = { class = "delegation_participation" }, + content = function() + slot.put("

-----> Participation
") + end + } end - } + slot.put("
") + end end - end + } end - } - end - + ui.link{ + content = function() + ui.image{ static = "icons/16/table_go.png" } + if scope == "global" and delegation then + slot.put(_"Change global delegation") + elseif scope == "global" and not delegation then + slot.put(_"Set global delegation") + elseif scope == "area" and delegation and delegation.area_id then + slot.put(_"Change area delegation") + elseif scope == "area" and not (delegation and delegation.area_id) then + slot.put(_"Set area delegation") + elseif scope == "issue" and delegation and delegation.issue_id then + slot.put(_"Change issue delegation") + elseif scope == "issue" and not (delegation and delegation.issue_id) then + slot.put(_"Set issue delegation") + end + end, + module = "delegation", + view = "new", + params = { + area_id = area_id, + issue_id = issue_id + } + } + end + } end) diff -r 768faea1096d -r 80c215dbf076 app/main/delegation/new.lua --- a/app/main/delegation/new.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/delegation/new.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,18 +1,59 @@ local area = Area:by_id(param.get("area_id", atom.integer)) if area then slot.put_into("title", encode.html(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name))) + util.help("delegation.new.area") end local issue = Issue:by_id(param.get("issue_id", atom.integer)) if issue then slot.put_into("title", encode.html(_"Set delegation for Issue ##{number} in Area '#{area_name}'":gsub("#{number}", issue.id):gsub("#{area_name}", issue.area.name))) + util.help("delegation.new.issue") end +if not area and not issue then + slot.put_into("title", encode.html(_"Set global delegation")) + util.help("delegation.new.global") +end + +slot.select("actions", function() + if issue then + ui.link{ + module = "issue", + view = "show", + id = issue.id, + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + } + elseif area then + ui.link{ + module = "area", + view = "show", + id = area.id, + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + } + else + ui.link{ + module = "index", + view = "index", + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + } + end +end) + + local contact_members = Member:new_selector() :add_where{ "contact.member_id = ?", app.session.member.id } :join("contact", nil, "member.id = contact.other_member_id") - :add_order_by("member.login") + :add_order_by("member.name") :exec() @@ -27,19 +68,29 @@ routing = { default = { mode = "redirect", - module = area and "area" or "issue", - view = "show", - id = area and area.id or issue.id, + module = area and "area" or issue and "issue" or "index", + view = (area or issue) and "show" or "index", + id = area and area.id or issue and issue.id or nil, } }, content = function() + records = { + { + id = "-1", + name = _"No delegation" + } + } + for i, record in ipairs(contact_members) do + records[#records+1] = record + end + ui.field.select{ label = _"Trustee", name = "trustee_id", - foreign_records = contact_members, + foreign_records = records, foreign_id = "id", - foreign_name = "name" + foreign_name = "name", } ui.submit{ text = _"Save" } end -} \ No newline at end of file +} diff -r 768faea1096d -r 80c215dbf076 app/main/draft/_action/add.lua --- a/app/main/draft/_action/add.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/draft/_action/add.lua Thu Dec 10 12:00:00 2009 +0100 @@ -4,6 +4,17 @@ local draft = Draft:new() draft.author_id = app.session.member.id draft.initiative_id = initiative.id + local formatting_engine = param.get("formatting_engine") + local formatting_engine_valid = false + for fe, dummy in pairs(config.formatting_engine_executeables) do + if formatting_engine == fe then + formatting_engine_valid = true + end + end + if not formatting_engine_valid then + error("invalid formatting engine!") + end + draft.formatting_engine = formatting_engine draft.content = param.get("content") draft:save() diff -r 768faea1096d -r 80c215dbf076 app/main/draft/_show.lua --- a/app/main/draft/_show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/draft/_show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -9,9 +9,9 @@ ui.field.text{ label = _"Author", name = "author_name" } ui.field.timestamp{ label = _"Created at", name = "created" } ui.container{ - attr = { class = "draft_content" }, + attr = { class = "draft_content wiki" }, content = function() - slot.put(format.wiki_text(draft.content)) + slot.put(format.wiki_text(draft.content, draft.formatting_engine)) end } end diff -r 768faea1096d -r 80c215dbf076 app/main/draft/new.lua --- a/app/main/draft/new.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/draft/new.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,7 +1,19 @@ -slot.put_into("title", _"Add new draft") +slot.put_into("title", _"Edit draft") local initiative = Initiative:by_id(param.get("initiative_id")) +slot.select("actions", function() + ui.link{ + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + module = "initiative", + view = "show", + id = initiative.id + } +end) + ui.form{ record = initiative.current_draft, attr = { class = "vertical" }, @@ -19,6 +31,16 @@ content = function() ui.field.text{ label = _"Author", value = app.session.member.name, readonly = true } + ui.field.select{ + label = _"Wiki engine", + name = "formatting_engine", + foreign_records = { + { id = "rocketwiki", name = "RocketWiki" }, + { id = "compat", name = _"Traditional wiki syntax" } + }, + foreign_id = "id", + foreign_name = "name" + } ui.field.text{ label = _"Content", name = "content", diff -r 768faea1096d -r 80c215dbf076 app/main/help/_action/update.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/help/_action/update.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,15 @@ +local help_ident = param.get("help_ident") +local hide = param.get("hide", atom.boolean) + +local setting_key = "liquidfeedback_frontend_hidden_help_" .. help_ident +local setting = Setting:by_pk(app.session.member.id, setting_key) + +if hide == true and not setting then + setting = Setting:new() + setting.member_id = app.session.member.id + setting.key = setting_key + setting.value = "hidden" + setting:save() +elseif hide == false and setting then + setting:destroy() +end diff -r 768faea1096d -r 80c215dbf076 app/main/index/_action/set_lang.lua --- a/app/main/index/_action/set_lang.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/index/_action/set_lang.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,3 +1,5 @@ -app.session.lang = param.get("lang") - -app.session:save() \ No newline at end of file +local lang = param.get("lang") +if lang == "de" or lang == "en" then + app.session.lang = param.get("lang") + app.session:save() +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 app/main/index/change_password.lua --- a/app/main/index/change_password.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/index/change_password.lua Thu Dec 10 12:00:00 2009 +0100 @@ -12,6 +12,8 @@ } end) +util.help("index.change_password", _"Change password") + ui.form{ attr = { class = "vertical" }, module = "index", diff -r 768faea1096d -r 80c215dbf076 app/main/index/index.lua --- a/app/main/index/index.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/index/index.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,10 +1,11 @@ slot.select("title", function() - ui.image{ - attr = { class = "avatar" }, - module = "member", - view = "avatar", - extension = "jpg", - id = app.session.member.id + execute.view{ + module = "member_image", + view = "_show", + params = { + member = app.session.member, + image_type = "avatar" + } } end) @@ -41,27 +42,28 @@ slot.put_into("title", encode.html(config.app_title)) slot.select("actions", function() - slot.put(_"Logged in as:") - slot.put(" ") - slot.put(app.session.member.login) - slot.put(" | ") + + ui.link{ + content = function() + ui.image{ static = "icons/16/application_form.png" } + slot.put(_"Edit my profile") + end, + module = "member", + view = "edit" + } ui.link{ content = function() ui.image{ static = "icons/16/user_gray.png" } - slot.put(_"Upload avatar") + slot.put(_"Upload images") end, module = "member", - view = "edit_avatar" + view = "edit_images" } - ui.link{ - content = function() - ui.image{ static = "icons/16/application_form.png" } - slot.put(_"Edit my page") - end, - module = "member", - view = "edit" + execute.view{ + module = "delegation", + view = "_show_box" } ui.link{ @@ -72,8 +74,28 @@ module = "index", view = "change_password" } + end) +local lang = locale.get("lang") +local basepath = request.get_app_basepath() +local file_name = basepath .. "/locale/motd/" .. lang .. ".txt" +local file = io.open(file_name) +if file ~= nil then + local help_text = file:read("*a") + if #help_text > 0 then + ui.container{ + attr = { class = "motd wiki" }, + content = function() + slot.put(format.wiki_text(help_text)) + end + } + end +end + + +util.help("index.index", _"Home") + execute.view{ module = "member", view = "_show", diff -r 768faea1096d -r 80c215dbf076 app/main/initiative/_action/create.lua --- a/app/main/initiative/_action/create.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/initiative/_action/create.lua Thu Dec 10 12:00:00 2009 +0100 @@ -29,6 +29,17 @@ local draft = Draft:new() draft.initiative_id = initiative.id +local formatting_engine = param.get("formatting_engine") +local formatting_engine_valid = false +for fe, dummy in pairs(config.formatting_engine_executeables) do + if formatting_engine == fe then + formatting_engine_valid = true + end +end +if not formatting_engine_valid then + error("invalid formatting engine!") +end +draft.formatting_engine = formatting_engine draft.content = param.get("draft") draft.author_id = app.session.member.id draft:save() diff -r 768faea1096d -r 80c215dbf076 app/main/initiative/_list.lua --- a/app/main/initiative/_list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/initiative/_list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -66,7 +66,7 @@ local max_value = record.issue.voter_count ui.bargraph{ max_value = max_value, - width = 200, + width = 100, bars = { { color = "#0a0", value = record.positive_votes }, { color = "#aaa", value = max_value - record.negative_votes - record.positive_votes }, @@ -78,7 +78,7 @@ local max_value = (record.issue.population or 0) ui.bargraph{ max_value = max_value, - width = 200, + width = 100, bars = { { color = "#0a0", value = (record.satisfied_supporter_count or 0) }, { color = "#8f8", value = (record.supporter_count or 0) - (record.satisfied_supporter_count or 0) }, diff -r 768faea1096d -r 80c215dbf076 app/main/initiative/edit.lua --- a/app/main/initiative/edit.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/initiative/edit.lua Thu Dec 10 12:00:00 2009 +0100 @@ -2,6 +2,18 @@ slot.put_into("title", _"Edit initiative") +slot.select("actions", function() + ui.link{ + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + module = "initiative", + view = "show", + id = initiative.id + } +end) + ui.form{ record = initiative, module = "initiative", diff -r 768faea1096d -r 80c215dbf076 app/main/initiative/new.lua --- a/app/main/initiative/new.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/initiative/new.lua Thu Dec 10 12:00:00 2009 +0100 @@ -38,8 +38,18 @@ foreign_name = "name" } end - ui.field.text{ label = _"Name", name = "name" } - ui.field.text{ label = _"Discussion URL", name = "discussion_url" } + ui.field.text{ label = _"Name", name = "name" } + ui.field.text{ label = _"Discussion URL", name = "discussion_url" } + ui.field.select{ + label = _"Wiki engine", + name = "formatting_engine", + foreign_records = { + { id = "rocketwiki", name = "RocketWiki" }, + { id = "compat", name = _"Traditional wiki syntax" } + }, + foreign_id = "id", + foreign_name = "name" + } ui.field.text{ label = _"Draft", name = "draft", multiline = true, attr = { style = "height: 50ex;" } } ui.submit{ text = _"Save" } end diff -r 768faea1096d -r 80c215dbf076 app/main/initiative/show.lua --- a/app/main/initiative/show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/initiative/show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,5 +1,15 @@ local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() + + +execute.view{ + module = "issue", + view = "_show_head", + params = { issue = initiative.issue } +} + +local initiator = Initiator:by_pk(initiative.id, app.session.member.id) + --slot.put_into("html_head", '') execute.view{ @@ -8,6 +18,8 @@ params = { initiative = initiative } } +--[[ + execute.view{ module = "delegation", view = "_show_box", @@ -20,6 +32,7 @@ params = { issue = initiative.issue } } + slot.select("path", function() ui.link{ content = _"Area '#{name}'":gsub("#{name}", initiative.issue.area.name), @@ -37,29 +50,27 @@ end) slot.put_into("title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) )) +--]] + +slot.put_into("sub_title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) )) slot.select("actions", function() - local initiator = Initiator:by_pk(initiative.id, app.session.member.id) - - if initiator then + if not initiative.issue.fully_frozen and not initiative.issue.closed then ui.link{ content = function() - ui.image{ static = "icons/16/script_add.png" } - slot.put(_"Edit draft") + ui.image{ static = "icons/16/script.png" } + slot.put(_"Show other initiatives") end, - module = "draft", - view = "new", - params = { initiative_id = initiative.id } + module = "issue", + view = "show", + id = initiative.issue.id } - end - - if not initiative.issue.fully_frozen and not initiative.issue.closed then ui.link{ attr = { class = "action" }, content = function() ui.image{ static = "icons/16/script_add.png" } - slot.put(_"Create alternative initiative" ) + slot.put(_"Create alternative initiative") end, module = "initiative", view = "new", @@ -68,28 +79,50 @@ end -- ui.twitter("http://example.com/i" .. tostring(initiative.id) .. " " .. initiative.name) - if initiative.discussion_url and #initiative.discussion_url > 0 then - ui.link{ - attr = { - target = _"blank", - title = initiative.discussion_url - }, +end) + + +util.help("initiative.show") + + +ui.container{ + attr = { class = "vertical" }, + content = function() + ui.container{ + attr = { class = "ui_field_label" }, + content = _"Discussion URL" + } + ui.tag{ + tag = "span", content = function() - ui.image{ static = "icons/16/comments.png" } - slot.put(_"External discussion") - end, - external = initiative.discussion_url + if initiative.discussion_url and #initiative.discussion_url > 0 then + ui.link{ + attr = { + class = "actions", + target = _"blank", + title = initiative.discussion_url + }, + content = function() + slot.put(encode.html(initiative.discussion_url)) + end, + external = initiative.discussion_url + } + end + slot.put(" ") + if initiator then + ui.link{ + attr = { class = "actions" }, + content = _"(change URL)", + module = "initiative", + view = "edit", + id = initiative.id + } + end + end } end - if initiator then - ui.link{ - content = _"(change)", - module = "initiative", - view = "edit", - id = initiative.id - } - end -end) +} + ui.container{ @@ -122,7 +155,14 @@ }, attr = { class = "vertical" }, content = function() - ui.field.text{ label = _"Name", name = "name" } + local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false + if not supported then + ui.field.text{ + attr = { class = "warning" }, + value = _"You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter." + } + end + ui.field.text{ label = _"Title (80 chars max)", name = "name" } ui.field.text{ label = _"Description", name = "description", multiline = true } ui.field.select{ label = _"Degree", @@ -183,11 +223,23 @@ end end + ui.tabs{ { name = "current_draft", label = _"Current draft", content = function() + if initiator then + ui.link{ + content = function() + ui.image{ static = "icons/16/script_add.png" } + slot.put(_"Edit draft") + end, + module = "draft", + view = "new", + params = { initiative_id = initiative.id } + } + end execute.view{ module = "draft", view = "_show", params = { draft = initiative.current_draft } } end }, @@ -195,7 +247,14 @@ name = "suggestion", label = _"Suggestions", content = function() - execute.view{ module = "suggestion", view = "_list", params = { suggestions_selector = initiative:get_reference_selector("suggestions") } } + execute.view{ + module = "suggestion", + view = "_list", + params = { + initiative = initiative, + suggestions_selector = initiative:get_reference_selector("suggestions") + } + } slot.put("
") if not initiative.issue.frozen and not initiative.issue.closed then ui.link{ @@ -220,8 +279,8 @@ initiative = initiative, members_selector = initiative:get_reference_selector("supporting_members_snapshot") :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") - :join("direct_population_snapshot", nil, "direct_population_snapshot.event = issue.latest_snapshot_event AND direct_population_snapshot.issue_id = issue.id AND direct_population_snapshot.member_id = member.id") - :add_field("direct_population_snapshot.weight") + :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") + :add_field("direct_interest_snapshot.weight") :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") } } diff -r 768faea1096d -r 80c215dbf076 app/main/interest/_show_box.lua --- a/app/main/interest/_show_box.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/interest/_show_box.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,73 +1,71 @@ local issue = param.get("issue", "table") - -slot.select("interest", function() - local interest = Interest:by_pk(issue.id, app.session.member.id) +local interest = Interest:by_pk(issue.id, app.session.member.id) - ui.container{ - attr = { - class = "head", - onclick = "document.getElementById('interest_content').style.display = 'block';" - }, - content = function() - if interest then - ui.field.text{ value = _"You are interested. [more]" } - else - ui.field.text{ value = _"You are not interested. [more]" } - end - end - } +if interest then + slot.select("actions", function() ui.container{ - attr = { class = "content", id = "interest_content" }, + attr = { class = "interest vote_info"}, content = function() - ui.container{ - attr = { - class = "close", - style = "cursor: pointer;", - onclick = "document.getElementById('interest_content').style.display = 'none';" - }, - content = _"X" - } - if interest then - ui.link{ - content = _"Remove my interest", - module = "interest", - action = "update", - params = { issue_id = issue.id, delete = true }, - routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } + ui.container{ + attr = { + class = "head head_active", + onclick = "document.getElementById('interest_content').style.display = 'block';" + }, + content = function() + slot.put(_"Your are interested") + ui.image{ + static = "icons/16/dropdown.png" + } + end } - slot.put("
") - slot.put("
") - if interest.autoreject then - ui.field.text{ value = _"Autoreject is on." } - ui.link{ - content = _"Remove autoreject", - module = "interest", - action = "update", - params = { issue_id = issue.id, autoreject = false }, - routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } - } - else - ui.field.text{ value = _"Autoreject is off." } - ui.link{ - content = _"Set autoreject", - module = "interest", - action = "update", - params = { issue_id = issue.id, autoreject = true }, - routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } - } - end - else - ui.link{ - content = _"Add my interest to this issue", - module = "interest", - action = "update", - params = { issue_id = issue.id }, - routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } + + ui.container{ + attr = { class = "content", id = "interest_content" }, + content = function() + ui.container{ + attr = { + class = "close", + style = "cursor: pointer;", + onclick = "document.getElementById('interest_content').style.display = 'none';" + }, + content = function() + ui.image{ static = "icons/16/cross.png" } + end + } + ui.link{ + content = _"Remove my interest", + module = "interest", + action = "update", + params = { issue_id = issue.id, delete = true }, + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } + } + slot.put("
") + slot.put("
") + if interest.autoreject then + ui.field.text{ value = _"Autoreject is on." } + ui.link{ + content = _"Remove autoreject", + module = "interest", + action = "update", + params = { issue_id = issue.id, autoreject = false }, + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } + } + else + ui.field.text{ value = _"Autoreject is off." } + ui.link{ + content = _"Set autoreject", + module = "interest", + action = "update", + params = { issue_id = issue.id, autoreject = true }, + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } + } + end + end } end - end - } -end) + } + end) +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 app/main/issue/_show_head.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/issue/_show_head.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,56 @@ +local issue = param.get("issue", "table") + +slot.put_into("html_head", '') + +slot.select("path", function() + ui.link{ + content = _"Area '#{name}'":gsub("#{name}", issue.area.name), + module = "area", + view = "show", + id = issue.area.id + } +end) + +slot.put_into("title", encode.html(_"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name))) + +slot.select("actions", function() + execute.view{ + module = "interest", + view = "_show_box", + params = { issue = issue } + } + + execute.view{ + module = "delegation", + view = "_show_box", + params = { issue_id = issue.id } + } + + -- TODO performance + local interest = Interest:by_pk(issue.id, app.session.member.id) + if not issue.closed and not issue.fully_frozen then + if not interest then + ui.link{ + content = function() + ui.image{ static = "icons/16/user_add.png" } + slot.put(_"Add my interest") + end, + module = "interest", + action = "update", + params = { issue_id = issue.id }, + routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } } + } + end + end + + +end) + + +execute.view{ + module = "issue", + view = "_show_box", + params = { issue = issue } +} + +-- ui.twitter("http://example.com/t" .. tostring(issue.id)) diff -r 768faea1096d -r 80c215dbf076 app/main/issue/show.lua --- a/app/main/issue/show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/issue/show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,52 +1,12 @@ local issue = Issue:by_id(param.get_id()) -slot.put_into("html_head", '') - -slot.select("path", function() - ui.link{ - content = _"Area '#{name}'":gsub("#{name}", issue.area.name), - module = "area", - view = "show", - id = issue.area.id - } -end) - -slot.put_into("title", encode.html(_"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name))) - -slot.select("actions", function() - if not issue.closed then - ui.link{ - content = function() - ui.image{ static = "icons/16/table_go.png" } - slot.put(_"Delegate") - end, - module = "delegation", - view = "new", - params = { issue_id = issue.id } - } - end - - ui.twitter("http://example.com/t" .. tostring(issue.id)) - -end) - execute.view{ - module = "interest", - view = "_show_box", + module = "issue", + view = "_show_head", params = { issue = issue } } -execute.view{ - module = "delegation", - view = "_show_box", - params = { issue_id = issue.id } -} - -execute.view{ - module = "issue", - view = "_show_box", - params = { issue = issue } -} +util.help("issue.show") ui.tabs{ { diff -r 768faea1096d -r 80c215dbf076 app/main/member/_action/update_avatar.lua --- a/app/main/member/_action/update_avatar.lua Mon Nov 30 12:00:00 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -local member_id = app.session.member_id - -local member_image = MemberImage:by_pk(member_id, "avatar", false) -local member_image_scaled = MemberImage:by_pk(member_id, "avatar", true) - -if param.get("avatar_delete", atom.boolean) then - if member_image then - member_image:destroy() - end - if member_image_scaled then - member_image_scaled:destroy() - end - slot.put_into("notice", _"Avatar has been deleted") - return -end - -local data = param.get("avatar") - -local data_scaled, err, status = os.pfilter(data, "convert", "-", "-thumbnail", "48x48", "jpeg:-") - -if status ~= 0 or data_scaled == nil then - error("error while converting image") -end - -if not member_image then - member_image = MemberImage:new() - member_image.member_id = member_id - member_image.image_type = "avatar" - member_image.scaled = false - member_image.data = "" - member_image:save() -end - -if not member_image_scaled then - member_image_scaled = MemberImage:new() - member_image_scaled.member_id = member_id - member_image_scaled.image_type = "avatar" - member_image_scaled.scaled = true - member_image_scaled.content_type = true - member_image_scaled.data = "" - member_image_scaled:save() -end - -if data and #data > 0 then - db:query{ "UPDATE member_image SET data = $ WHERE member_id = ? AND image_type='avatar' AND scaled=FALSE", { db:quote_binary(data) }, app.session.member.id } -end - -if data_scaled and #data_scaled > 0 then - db:query{ "UPDATE member_image SET data = $ WHERE member_id = ? AND image_type='avatar' AND scaled=TRUE", { db:quote_binary(data_scaled) }, app.session.member.id } -end - -slot.put_into("notice", _"Avatar has been updated") diff -r 768faea1096d -r 80c215dbf076 app/main/member/_action/update_images.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member/_action/update_images.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,73 @@ +local member_id = app.session.member_id + +local deleted = 0 +local updated = 0 + +for i, image_type in ipairs{"avatar", "photo"} do + + local member_image = MemberImage:by_pk(member_id, image_type, false) + local member_image_scaled = MemberImage:by_pk(member_id, image_type, true) + + if param.get(image_type .. "_delete", atom.boolean) then + if member_image then + member_image:destroy() + end + if member_image_scaled then + member_image_scaled:destroy() + end + deleted = deleted + 1 + else + + local data = param.get(image_type) + if data and #data > 0 and #data < 1024*1024 then + local convert_func = config.member_image_convert_func[image_type] + local data_scaled, err, status = convert_func(data) + if status ~= 0 or data_scaled == nil then + error("error while converting image") + end + + if not member_image then + member_image = MemberImage:new() + member_image.member_id = member_id + member_image.image_type = image_type + member_image.scaled = false + member_image.data = "" + member_image:save() + end + + if not member_image_scaled then + member_image_scaled = MemberImage:new() + member_image_scaled.member_id = member_id + member_image_scaled.image_type = image_type + member_image_scaled.scaled = true + member_image_scaled.content_type = true + member_image_scaled.data = "" + member_image_scaled:save() + end + + if data and #data > 0 then + db:query{ "UPDATE member_image SET data = $ WHERE member_id = ? AND image_type='" .. image_type .. "' AND scaled=FALSE", { db:quote_binary(data) }, app.session.member.id } + end + + if data_scaled and #data_scaled > 0 then + db:query{ "UPDATE member_image SET data = $ WHERE member_id = ? AND image_type='" .. image_type .. "' AND scaled=TRUE", { db:quote_binary(data_scaled) }, app.session.member.id } + end + + updated = updated + 1 + end + end +end + +if updated > 0 then + slot.put_into("notice", _("#{number} Image(s) has been updated", { number = updated })) +end +if updated > 0 and deleted > 0 then + slot.put_into("notice", " · ") +end +if deleted > 0 then + slot.put_into("notice", _("#{number} Image(s) has been deleted", { number = deleted })) +end + +if updated == 0 and deleted == 0 then + slot.put_into("warning", _("No changes to your images were made")) +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 app/main/member/_show.lua --- a/app/main/member/_show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/member/_show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,24 +1,116 @@ local member = param.get("member", "table") -ui.form{ - attr = { class = "vertical" }, - record = member, - readonly = true, - content = function() - if member.admin then - ui.field.boolean{ label = _"Admin?", name = "admin" } +ui.tabs{ + { + name = "profile", + label = _"Profile", + content = function() + ui.form{ + attr = { class = "member vertical" }, + record = member, + readonly = true, + content = function() + + ui.container{ + attr = { class = "right" }, + content = function() + + execute.view{ + module = "member_image", + view = "_show", + params = { + member = member, + image_type = "photo" + } + } + + ui.container{ + attr = { class = "contact_data" }, + content = function() + end + } + + end + } + + if member.admin then + ui.field.boolean{ label = _"Admin?", name = "admin" } + end + if member.locked then + ui.field.boolean{ label = _"Locked?", name = "locked" } + end + if member.ident_number then + ui.field.text{ label = _"Ident number", name = "ident_number" } + end + ui.field.text{ label = _"Name", name = "name" } + + if member.realname and #member.realname > 0 then + ui.field.text{ label = _"Real name", name = "realname" } + end + if member.email and #member.email > 0 then + ui.field.text{ label = _"email", name = "email" } + end + if member.xmpp_address and #member.xmpp_address > 0 then + ui.field.text{ label = _"xmpp", name = "xmpp_address" } + end + if member.website and #member.website > 0 then + ui.field.text{ label = _"Website", name = "website" } + end + if member.phone and #member.phone > 0 then + ui.field.text{ label = _"Phone", name = "phone" } + end + if member.mobile_phone and #member.mobile_phone > 0 then + ui.field.text{ label = _"Mobile phone", name = "mobile_phone" } + end + if member.address and #member.address > 0 then + ui.container{ + content = function() + ui.tag{ + tag = "label", + attr = { class = "ui_field_label" }, + content = _"Address" + } + ui.tag{ + tag = "span", + content = function() + slot.put(encode.html_newlines(member.address)) + end + } + end + } + end + if member.profession and #member.profession > 0 then + ui.field.text{ label = _"Profession", name = "profession" } + end + if member.birthday and #member.birthday > 0 then + ui.field.text{ label = _"Birthday", name = "birthday" } + end + if member.organizational_unit and #member.organizational_unit > 0 then + ui.field.text{ label = _"Organizational unit", name = "organizational_unit" } + end + if member.internal_posts and #member.internal_posts > 0 then + ui.field.text{ label = _"Internal posts", name = "internal_posts" } + end + if member.external_memberships and #member.external_memberships > 0 then + ui.field.text{ label = _"Memberships", name = "external_memberships", multiline = true } + end + if member.external_posts and #member.external_posts > 0 then + ui.field.text{ label = _"Posts", name = "external_posts", multiline = true } + end + slot.put('
') + + end + } + if member.statement and #member.statement > 0 then + ui.container{ + attr = { class = "member_statement wiki" }, + content = function() + slot.put(format.wiki_text(member.statement)) + end + } + end end - if member.locked then - ui.field.boolean{ label = _"Locked?", name = "locked" } - end - if member.ident_number then - ui.field.text{ label = _"Ident number", name = "ident_number" } - end - ui.submit{ text = _"Save" } - end -} - -ui.tabs{ + }, { name = "areas", label = _"Areas", @@ -42,8 +134,8 @@ end }, { - name = "initiatives", - label = _"Initiatives", + name = "supported_initiatives", + label = _"Supported initiatives", content = function() execute.view{ module = "initiative", @@ -53,6 +145,17 @@ end }, { + name = "initiatied_initiatives", + label = _"Initiated initiatives", + content = function() + execute.view{ + module = "initiative", + view = "_list", + params = { initiatives_selector = member:get_reference_selector("initiated_initiatives") } + } + end + }, + { name = "incoming_delegations", label = _"Incoming delegations", content = function() @@ -64,7 +167,7 @@ end }, { - name = "outgoing_delegations", + name = "Outgoing delegations", label = _"Outgoing delegations", content = function() execute.view{ diff -r 768faea1096d -r 80c215dbf076 app/main/member/_show_thumb.lua --- a/app/main/member/_show_thumb.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/member/_show_thumb.lua Thu Dec 10 12:00:00 2009 +0100 @@ -58,19 +58,21 @@ end end } - + ui.link{ attr = { title = _"Show member" }, module = "member", view = "show", id = member.id, content = function() - ui.image{ - attr = { width = 48, height = 48 }, - module = "member", - view = "avatar", - id = member.id, - extension = "jpg" + execute.view{ + module = "member_image", + view = "_show", + params = { + member = member, + image_type = "avatar", + show_dummy = true + } } ui.container{ attr = { class = "member_name" }, diff -r 768faea1096d -r 80c215dbf076 app/main/member/_show_thumb.lua.orig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member/_show_thumb.lua.orig Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,86 @@ +local member = param.get("member", "table") + +local issue = param.get("issue", "table") +local initiative = param.get("initiative", "table") +local trustee = param.get("trustee", "table") + +local name +if member.name_highlighted then + name = encode.highlight(member.name_highlighted) +else + name = encode.html(member.name) +end + +ui.container{ + attr = { class = "member_thumb" }, + content = function() + ui.container{ + attr = { class = "flags" }, + content = function() + if (issue or initiative) and member.weight > 1 then + local module + if issue then + module = "interest" + elseif initiative then + module = "supporter" + end + ui.link{ + attr = { title = _"Number of incoming delegations, follow link to see more details" }, + content = _("+ #{weight}", { weight = member.weight - 1 }), + module = module, + view = "show_incoming", + params = { + member_id = member.id, + initiative_id = initiative and initiative.id or nil, + issue_id = issue and issue.id or nil + } + } + end + -- TODO performance + local contact = Contact:by_pk(app.session.member.id, member.id) + if contact then + ui.image{ + attr = { + alt = _"You have saved this member as contact", + title = _"You have saved this member as contact" + }, + static = "icons/16/bullet_disk.png" + } + end + end + } + + ui.link{ + attr = { title = _"Show member" }, + module = "member", + view = "show", + id = member.id, + content = function() + execute.view{ + module = "member_image", + view = "_show", + params = { + member = member, + image_type = "avatar", + show_dummy = true + } + } + end + } + + ui.link{ + attr = { title = _"Show member" }, + module = "member", + view = "show", + id = member.id, + content = function() + ui.container{ + attr = { class = "member_name" }, + content = function() + slot.put(name) + end + } + end + } + end +} diff -r 768faea1096d -r 80c215dbf076 app/main/member/avatar.lua --- a/app/main/member/avatar.lua Mon Nov 30 12:00:00 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -local record = MemberImage:by_pk(param.get_id(), "avatar", true) - -if record == nil then - print('Location: ' .. encode.url{ static = 'avatar.jpg' } .. '\n\n') - exit() -end - -print('Content-type: ' .. record.content_type .. '\n') - -if record then - io.stdout:write(record.data) -else -end - -exit() diff -r 768faea1096d -r 80c215dbf076 app/main/member/edit.lua --- a/app/main/member/edit.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/member/edit.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,4 +1,4 @@ -slot.put_into("title", _"Edit my page") +slot.put_into("title", _"Edit my profile") slot.select("actions", function() ui.link{ @@ -11,6 +11,8 @@ } end) +util.help("member.edit", _"Edit my page") + ui.form{ record = app.session.member, attr = { class = "vertical" }, diff -r 768faea1096d -r 80c215dbf076 app/main/member/edit_avatar.lua --- a/app/main/member/edit_avatar.lua Mon Nov 30 12:00:00 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -slot.put_into("title", _"Upload avatar") - -slot.select("actions", function() - ui.link{ - content = function() - ui.image{ static = "icons/16/cancel.png" } - slot.put(_"Cancel") - end, - module = "index", - view = "index" - } -end) - -ui.form{ - record = app.session.member, - attr = { - class = "vertical", - enctype = 'multipart/form-data' - }, - module = "member", - action = "update_avatar", - routing = { - ok = { - mode = "redirect", - module = "index", - view = "index" - } - }, - content = function() - ui.field.image{ field_name = "avatar", label = _"Avatar" } - ui.submit{ value = _"Save" } - end -} \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 app/main/member/edit_images.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member/edit_images.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,52 @@ +slot.put_into("title", _"Upload images") + +slot.select("actions", function() + ui.link{ + content = function() + ui.image{ static = "icons/16/cancel.png" } + slot.put(_"Cancel") + end, + module = "index", + view = "index" + } +end) + +util.help("member.edit_images", _"Images") + +ui.form{ + record = app.session.member, + attr = { + class = "vertical", + enctype = 'multipart/form-data' + }, + module = "member", + action = "update_images", + routing = { + ok = { + mode = "redirect", + module = "index", + view = "index" + } + }, + content = function() + execute.view{ + module = "member_image", + view = "_show", + params = { + member = app.session.member, + image_type = "avatar" + } + } + ui.field.image{ field_name = "avatar", label = _"Avatar" } + execute.view{ + module = "member_image", + view = "_show", + params = { + member = app.session.member, + image_type = "photo" + } + } + ui.field.image{ field_name = "photo", label = _"Photo" } + ui.submit{ value = _"Save" } + end +} \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 app/main/member/list.lua --- a/app/main/member/list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/member/list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,7 +1,9 @@ slot.put_into("title", _"Member list") +util.help("member.list") + execute.view{ module = "member", view = "_list", - params = { members_selector = Member:new_selector():add_order_by("login") } + params = { members_selector = Member:new_selector():add_order_by("name") } } diff -r 768faea1096d -r 80c215dbf076 app/main/member/show.lua --- a/app/main/member/show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/member/show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,12 +1,13 @@ local member = Member:by_id(param.get_id()) slot.select("title", function() - ui.image{ - attr = { class = "avatar" }, - module = "member", - view = "avatar", - extension = "jpg", - id = member.id + execute.view{ + module = "member_image", + view = "_show", + params = { + member = member, + image_type = "avatar" + } } end) @@ -19,9 +20,15 @@ local contact = Contact:by_pk(app.session.member.id, member.id) if contact then slot.select("actions", function() - ui.field.text{ value = _"You have saved this member as contact." } + ui.container{ + attr = { class = "interest" }, + content = _"You have saved this member as contact." + } ui.link{ - text = _"Remove from contacts", + content = function() + ui.image{ static = "icons/16/book_delete.png" } + slot.put(encode.html(_"Remove from contacts")) + end, module = "contact", action = "remove_member", id = contact.other_member_id, @@ -60,6 +67,7 @@ end end +util.help("member.show", _"Member page") execute.view{ module = "member", diff -r 768faea1096d -r 80c215dbf076 app/main/member_image/_show.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member_image/_show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,27 @@ +local member = param.get("member", "table") +local image_type = param.get("image_type") +local show_dummy = param.get("show_dummy", atom.boolean) + +local image = member:get_reference_selector("images") + :add_where{ "image_type = ?", image_type } + :optional_object_mode() + :exec() +if image or show_dummy then + if config.fastpath_url_func then + ui.image{ + attr = { class = "member_image member_image_" .. image_type }, + external = config.fastpath_url_func(member.id, image_type) + } + else + ui.image{ + attr = { class = "member_image member_image_" .. image_type }, + module = "member_image", + view = "show", + extension = "jpg", + id = member.id, + params = { + image_type = image_type + } + } + end +end diff -r 768faea1096d -r 80c215dbf076 app/main/member_image/show.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main/member_image/show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,21 @@ +local image_type = param.get("image_type") +local record = MemberImage:by_pk(param.get_id(), image_type, true) + +if record == nil then + local default_file = config.member_image_default_file[image_type] + if default_file then + print('Location: ' .. encode.url{ static = default_file } .. '\n\n') + else + print('Location: ' .. encode.url{ static = 'icons/16/lightning.png' } .. '\n\n') + end + exit() +end + +print('Content-type: ' .. record.content_type .. '\n') + +if record then + io.stdout:write(record.data) +else +end + +exit() diff -r 768faea1096d -r 80c215dbf076 app/main/membership/_action/update.lua --- a/app/main/membership/_action/update.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/membership/_action/update.lua Thu Dec 10 12:00:00 2009 +0100 @@ -25,4 +25,4 @@ membership:save() -slot.put_into("notice", _"Membership updated") +--slot.put_into("notice", _"Membership updated") diff -r 768faea1096d -r 80c215dbf076 app/main/membership/_show_box.lua --- a/app/main/membership/_show_box.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/membership/_show_box.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,34 +1,40 @@ local area = param.get("area", "table") +local membership = Membership:by_pk(area.id, app.session.member.id) + slot.select("interest", function() - local membership = Membership:by_pk(area.id, app.session.member.id) - ui.container{ - attr = { - class = "head", - onclick = "document.getElementById('membership_content').style.display = 'block';" - }, - content = function() - if membership then - ui.field.text{ value = _"You are member. [more]" } - else - ui.field.text{ value = _"You are not a member. [more]" } + if membership then + + ui.container{ + attr = { + class = "head head_active", + onclick = "document.getElementById('membership_content').style.display = 'block';" + }, + content = function() + ui.image{ + static = "icons/16/user_green.png" + } + slot.put(_"You are member") + ui.image{ + static = "icons/16/dropdown.png" + } end - end - } - - ui.container{ - attr = { class = "content", id = "membership_content" }, - content = function() - ui.container{ - attr = { - class = "close", - style = "cursor: pointer;", - onclick = "document.getElementById('membership_content').style.display = 'none';" - }, - content = _"X" - } - if membership then + } + + ui.container{ + attr = { class = "content", id = "membership_content" }, + content = function() + ui.container{ + attr = { + class = "close", + style = "cursor: pointer;", + onclick = "document.getElementById('membership_content').style.display = 'none';" + }, + content = function() + ui.image{ static = "icons/16/cross.png" } + end + } ui.link{ content = _"Remove my membership", module = "membership", @@ -55,15 +61,26 @@ routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } } end - else - ui.link{ - content = _"Add my membership to this area", - module = "membership", - action = "update", - params = { area_id = area.id }, - routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } } + end + } + else + ui.link{ + content = function() + ui.image{ static = "icons/16/user_add.png" } + slot.put(_"Become a member") + end, + module = "membership", + action = "update", + params = { area_id = area.id }, + routing = { + default = { + mode = "redirect", + module = "area", + view = "show", + id = area.id } - end - end - } + } + } + end + end) diff -r 768faea1096d -r 80c215dbf076 app/main/suggestion/_list.lua --- a/app/main/suggestion/_list.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/suggestion/_list.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,228 +1,292 @@ + +local initiative = param.get("initiative", "table") local suggestions_selector = param.get("suggestions_selector", "table") -ui.paginate{ +ui.order{ + name = name, selector = suggestions_selector, + options = { + { + name = "all", + label = _"all", + order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id" + }, + { + name = "plus2", + label = _"must", + order_by = "plus2_unfulfilled_count + plus2_fulfilled_count DESC, id" + }, + { + name = "plus", + label = _"must/should", + order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id" + }, + { + name = "minus", + label = _"must/should not", + order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count DESC, id" + }, + { + name = "minus2", + label = _"must not", + order_by = "minus2_unfulfilled_count + minus2_fulfilled_count DESC, id" + }, + { + name = "unfulfilled", + label = _"not implemented", + order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id" + }, + { + name = "plus2_unfulfilled", + label = _"must", + order_by = "plus2_unfulfilled_count DESC, id" + }, + { + name = "plus_unfulfilled", + label = _"must/should", + order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id" + }, + { + name = "minus_unfulfilled", + label = _"must/should not", + order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count DESC, id" + }, + { + name = "minus2_unfulfilled", + label = _"must not", + order_by = "minus2_unfulfilled_count DESC, id" + }, + }, content = function() - ui.list{ - attr = { style = "table-layout: fixed;" }, - records = suggestions_selector:exec(), - columns = { - { - label = _"Suggestion", - content = function(record) - ui.link{ - text = record.name, - module = "suggestion", - view = "show", - id = record.id - } - end - }, - { - label = _"Collective opinion", - label_attr = { style = "width: 101px;" }, - content = function(record) - if record.minus2_unfulfilled_count then - local max_value = record.initiative.issue.population - ui.bargraph{ - max_value = max_value, - width = 100, - bars = { - { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count - record.minus2_fulfilled_count - record.minus1_fulfilled_count }, - { color = "#f88", value = record.minus1_unfulfilled_count + record.minus1_fulfilled_count }, - { color = "#a00", value = record.minus2_unfulfilled_count + record.minus2_fulfilled_count }, - { color = "#0a0", value = record.plus2_unfulfilled_count + record.plus2_fulfilled_count }, - { color = "#8f8", value = record.plus1_unfulfilled_count + record.plus1_fulfilled_count }, - { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count - record.plus1_fulfilled_count - record.plus2_fulfilled_count }, + ui.paginate{ + selector = suggestions_selector, + content = function() + ui.list{ + attr = { style = "table-layout: fixed;" }, + records = suggestions_selector:exec(), + columns = { + { + label = _"Suggestion", + content = function(record) + ui.link{ + text = record.name, + module = "suggestion", + view = "show", + id = record.id } - } - end - end - }, - { - label = _"My opinion", - content = function(record) - local degree - local opinion = Opinion:by_pk(app.session.member.id, record.id) - if opinion then - degree = opinion.degree - end - ui.link{ - attr = { class = "action" .. (degree == -2 and " active_red2" or "") }, - text = _"must not", - module = "opinion", - action = "update", - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, - params = { - suggestion_id = record.id, - degree = -2 - } - } - ui.link{ - attr = { class = "action" .. (degree == -1 and " active_red1" or "") }, - text = _"should not", - module = "opinion", - action = "update", - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, - params = { - suggestion_id = record.id, - degree = -1 - } - } - ui.link{ - attr = { class = "action" .. (degree == nil and " active" or "") }, - text = _"neutral", - module = "opinion", - action = "update", - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, - params = { - suggestion_id = record.id, - delete = true - } - } - ui.link{ - attr = { class = "action" .. (degree == 1 and " active_green1" or "") }, - text = _"should", - module = "opinion", - action = "update", - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, - params = { - suggestion_id = record.id, - degree = 1 - } - } - ui.link{ - attr = { class = "action" .. (degree == 2 and " active_green2" or "") }, - text = _"must", - module = "opinion", - action = "update", - routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, - params = { - suggestion_id = record.id, - degree = 2 - } - } - end - }, - { - content = function(record) - local opinion = Opinion:by_pk(app.session.member.id, record.id) - if opinion and not opinion.fulfilled then - ui.image{ static = "icons/16/cross.png" } - end - end - }, - { - label = _"Suggestion currently not implemented", - label_attr = { style = "width: 101px;" }, - content = function(record) - if record.minus2_unfulfilled_count then - local max_value = record.initiative.issue.population - ui.bargraph{ - max_value = max_value, - width = 100, - bars = { - { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count }, - { color = "#f88", value = record.minus1_unfulfilled_count }, - { color = "#a00", value = record.minus2_unfulfilled_count }, - { color = "#0a0", value = record.plus2_unfulfilled_count }, - { color = "#8f8", value = record.plus1_unfulfilled_count }, - { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count }, - } - } - end - end - }, - { - content = function(record) - local opinion = Opinion:by_pk(app.session.member.id, record.id) - if opinion and opinion.fulfilled then - ui.image{ static = "icons/16/tick.png" } - end - end - }, - { - label = _"Suggestion currently implemented", - label_attr = { style = "width: 101px;" }, - content = function(record) - if record.minus2_fulfilled_count then - local max_value = record.initiative.issue.population - ui.bargraph{ - max_value = max_value, - width = 100, - bars = { - { color = "#ddd", value = max_value - record.minus2_fulfilled_count - record.minus1_fulfilled_count }, - { color = "#f88", value = record.minus1_fulfilled_count }, - { color = "#a00", value = record.minus2_fulfilled_count }, - { color = "#0a0", value = record.plus2_fulfilled_count }, - { color = "#8f8", value = record.plus1_fulfilled_count }, - { color = "#ddd", value = max_value - record.plus1_fulfilled_count - record.plus2_fulfilled_count }, - } - } - end - end - }, - { - label_attr = { style = "width: 200px;" }, - content = function(record) - local degree - local opinion = Opinion:by_pk(app.session.member.id, record.id) - if opinion then - degree = opinion.degree - end - if opinion then - if not opinion.fulfilled then - local text = "" - if opinion.degree > 0 then - text = _"Mark suggestion as implemented and express satisfaction" - else - text = _"Mark suggestion as implemented and express dissatisfaction" + end + }, + { + label = _"Collective opinion", + label_attr = { style = "width: 101px;" }, + content = function(record) + if record.minus2_unfulfilled_count then + local max_value = record.initiative.issue.population + ui.bargraph{ + max_value = max_value, + width = 50, + bars = { + { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count - record.minus2_fulfilled_count - record.minus1_fulfilled_count }, + { color = "#f88", value = record.minus1_unfulfilled_count + record.minus1_fulfilled_count }, + { color = "#a00", value = record.minus2_unfulfilled_count + record.minus2_fulfilled_count }, + { color = "#0a0", value = record.plus2_unfulfilled_count + record.plus2_fulfilled_count }, + { color = "#8f8", value = record.plus1_unfulfilled_count + record.plus1_fulfilled_count }, + { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count - record.plus1_fulfilled_count - record.plus2_fulfilled_count }, + } + } + end + end + }, + { + label = _"My opinion", + content = function(record) + local degree + local opinion = Opinion:by_pk(app.session.member.id, record.id) + if opinion then + degree = opinion.degree end ui.link{ - attr = { class = "action" }, - text = text, + attr = { class = "action" .. (degree == -2 and " active_red2" or "") }, + text = _"must not", + module = "opinion", + action = "update", + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, + params = { + suggestion_id = record.id, + degree = -2 + } + } + ui.link{ + attr = { class = "action" .. (degree == -1 and " active_red1" or "") }, + text = _"should not", + module = "opinion", + action = "update", + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, + params = { + suggestion_id = record.id, + degree = -1 + } + } + ui.link{ + attr = { class = "action" .. (degree == nil and " active" or "") }, + text = _"neutral", module = "opinion", action = "update", routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, params = { suggestion_id = record.id, - fulfilled = true + delete = true } } - else - if opinion.degree > 0 then - text = _"Mark suggestion as not implemented and express dissatisfaction" - else - text = _"Mark suggestion as not implemented and express satisfaction" - end ui.link{ - attr = { class = "action" }, - text = text, + attr = { class = "action" .. (degree == 1 and " active_green1" or "") }, + text = _"should", + module = "opinion", + action = "update", + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, + params = { + suggestion_id = record.id, + degree = 1 + } + } + ui.link{ + attr = { class = "action" .. (degree == 2 and " active_green2" or "") }, + text = _"must", module = "opinion", action = "update", routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, params = { suggestion_id = record.id, - fulfilled = false + degree = 2 } } end - end - end - }, - { - content = function(record) - local opinion = Opinion:by_pk(app.session.member.id, record.id) - if opinion then - if (opinion.fulfilled and opinion.degree > 0) or (not opinion.fulfilled and opinion.degree < 0) then - ui.image{ static = "icons/16/thumb_up_green.png" } - else - ui.image{ static = "icons/16/thumb_down_red.png" } + }, + { + content = function(record) + local opinion = Opinion:by_pk(app.session.member.id, record.id) + if opinion and not opinion.fulfilled then + ui.image{ static = "icons/16/cross.png" } + end + end + }, + { + label = _"Suggestion currently not implemented", + label_attr = { style = "width: 101px;" }, + content = function(record) + if record.minus2_unfulfilled_count then + local max_value = record.initiative.issue.population + ui.bargraph{ + max_value = max_value, + width = 50, + bars = { + { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count }, + { color = "#f88", value = record.minus1_unfulfilled_count }, + { color = "#a00", value = record.minus2_unfulfilled_count }, + { color = "#0a0", value = record.plus2_unfulfilled_count }, + { color = "#8f8", value = record.plus1_unfulfilled_count }, + { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count }, + } + } + end + end + }, + { + content = function(record) + local opinion = Opinion:by_pk(app.session.member.id, record.id) + if opinion and opinion.fulfilled then + ui.image{ static = "icons/16/tick.png" } + end + end + }, + { + label = _"Suggestion currently implemented", + label_attr = { style = "width: 101px;" }, + content = function(record) + if record.minus2_fulfilled_count then + local max_value = record.initiative.issue.population + ui.bargraph{ + max_value = max_value, + width = 50, + bars = { + { color = "#ddd", value = max_value - record.minus2_fulfilled_count - record.minus1_fulfilled_count }, + { color = "#f88", value = record.minus1_fulfilled_count }, + { color = "#a00", value = record.minus2_fulfilled_count }, + { color = "#0a0", value = record.plus2_fulfilled_count }, + { color = "#8f8", value = record.plus1_fulfilled_count }, + { color = "#ddd", value = max_value - record.plus1_fulfilled_count - record.plus2_fulfilled_count }, + } + } + end end - end - end - }, - } + }, + { + label_attr = { style = "width: 200px;" }, + content = function(record) + local degree + local opinion = Opinion:by_pk(app.session.member.id, record.id) + if opinion then + degree = opinion.degree + end + if opinion then + if not opinion.fulfilled then + local text = "" + if opinion.degree > 0 then + text = _"Mark suggestion as implemented and express satisfaction" + else + text = _"Mark suggestion as implemented and express dissatisfaction" + end + ui.link{ + attr = { class = "action" }, + text = text, + module = "opinion", + action = "update", + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, + params = { + suggestion_id = record.id, + fulfilled = true + } + } + else + if opinion.degree > 0 then + text = _"Mark suggestion as not implemented and express dissatisfaction" + else + text = _"Mark suggestion as not implemented and express satisfaction" + end + ui.link{ + attr = { class = "action" }, + text = text, + module = "opinion", + action = "update", + routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } }, + params = { + suggestion_id = record.id, + fulfilled = false + } + } + end + end + end + }, + { + content = function(record) + local opinion = Opinion:by_pk(app.session.member.id, record.id) + if opinion then + if (opinion.fulfilled and opinion.degree > 0) or (not opinion.fulfilled and opinion.degree < 0) then + ui.image{ static = "icons/16/thumb_up_green.png" } + else + ui.image{ static = "icons/16/thumb_down_red.png" } + end + end + end + }, + } + } + end } end } + +if initiative then + ui.field.timestamp{ label = _"Last snapshot:", value = initiative.issue.snapshot } +end diff -r 768faea1096d -r 80c215dbf076 app/main/suggestion/show.lua --- a/app/main/suggestion/show.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/suggestion/show.lua Thu Dec 10 12:00:00 2009 +0100 @@ -23,10 +23,9 @@ view = "_list", params = { opinions_selector = Opinion:new_selector() - :add_field("member.login", "member_login") :add_field("member.name", "member_name") :add_where{ "suggestion_id = ?", suggestion.id } :join("member", nil, "member.id = opinion.member_id") :add_order_by("member.id DESC") } -} \ No newline at end of file +} diff -r 768faea1096d -r 80c215dbf076 app/main/supporter/_show_box.lua --- a/app/main/supporter/_show_box.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/supporter/_show_box.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,49 +1,64 @@ - slot.select("support", function() - local initiative = param.get("initiative", "table") - - if not initiative.issue.frozen and not initiative.issue.closed then - - local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false - - local text - if supported then - text = _"Direct supporter [change]" - else - text = _"No supporter [change]" - end - ui.container{ - attr = { - class = "head", - style = "cursor: pointer;", - onclick = "document.getElementById('support_content').style.display = 'block';" - }, - content = text - } + local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false - - ui.container{ - attr = { class = "content", id = "support_content" }, - content = function() - ui.container{ - attr = { - class = "close", - style = "cursor: pointer;", - onclick = "document.getElementById('support_content').style.display = 'none';" - }, - content = _"X" - } + ui.container{ + attr = { class = "actions" }, + content = function() + if not initiative.issue.frozen and not initiative.issue.closed then if supported then - ui.link{ + ui.container{ + attr = { + class = "head head_active", + style = "cursor: pointer;", + onclick = "document.getElementById('support_content').style.display = 'block';" + }, + content = function() + ui.image{ + static = "icons/16/thumb_up_green.png" + } + slot.put(_"Your are supporter") + ui.image{ + static = "icons/16/dropdown.png" + } + end + } + ui.container{ + attr = { class = "content", id = "support_content" }, content = function() - ui.image{ static = "icons/16/thumb_down_red.png" } - slot.put(_"Remove my support from this initiative") - end, - module = "initiative", - action = "remove_support", - id = initiative.id + ui.container{ + attr = { + class = "close", + style = "cursor: pointer;", + onclick = "document.getElementById('support_content').style.display = 'none';" + }, + content = function() + ui.image{ static = "icons/16/cross.png" } + end + } + if supported then + ui.link{ + content = function() + ui.image{ static = "icons/16/thumb_down_red.png" } + slot.put(_"Remove my support from this initiative") + end, + module = "initiative", + action = "remove_support", + id = initiative.id, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } + } + else + end + end } else ui.link{ @@ -53,11 +68,19 @@ end, module = "initiative", action = "add_support", - id = initiative.id + id = initiative.id, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } } end end - } - end - + end + } end) diff -r 768faea1096d -r 80c215dbf076 app/main/supporter/show_incoming.lua --- a/app/main/supporter/show_incoming.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/app/main/supporter/show_incoming.lua Thu Dec 10 12:00:00 2009 +0100 @@ -3,11 +3,11 @@ local member = Member:by_id(param.get("member_id", atom.integer)) local members_selector = Member:new_selector() - :join("delegating_population_snapshot", nil, "delegating_population_snapshot.member_id = member.id") - :add_where{ "delegating_population_snapshot.issue_id = ?", issue.id } - :add_where{ "delegating_population_snapshot.event = ?", issue.latest_snapshot_event } - :add_where{ "delegating_population_snapshot.delegate_member_ids[1] = ?", member.id } - :add_field{ "delegating_population_snapshot.weight" } + :join("delegating_interest_snapshot", nil, "delegating_interest_snapshot.member_id = member.id") + :add_where{ "delegating_interest_snapshot.issue_id = ?", issue.id } + :add_where{ "delegating_interest_snapshot.event = ?", issue.latest_snapshot_event } + :add_where{ "delegating_interest_snapshot.delegate_member_ids[1] = ?", member.id } + :add_field{ "delegating_interest_snapshot.weight" } execute.view{ module = "member", diff -r 768faea1096d -r 80c215dbf076 config/default.lua --- a/config/default.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/config/default.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,14 +1,25 @@ config.app_name = "LiquidFeedback" -config.app_version = "alpha4" +config.app_version = "alpha5" config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)" +config.app_logo = nil + config.app_service_provider = "Snake Oil
10000 Berlin
Germany" -config.member_image_convert = { - avatar = { "convert", "-", "-thumbnail", "48x48", "jpeg:-" } +config.member_image_convert_func = { + avatar = function(data) return os.pfilter(data, "convert", "jpeg:-", "-thumbnail", "48x48", "jpeg:-") end, + photo = function(data) return os.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end } +config.member_image_default_file = { + avatar = "avatar.jpg", + photo = nil +} + +config.fastpath_url_func = nil + + -- uncomment the following two lines to use C implementations of chosen -- functions and to disable garbage collection during the request, to -- increase speed: diff -r 768faea1096d -r 80c215dbf076 config/development.lua --- a/config/development.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/config/development.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,3 +1,6 @@ execute.config("default") -config.wiki_parser_executeable = "/opt/rocketwiki/rocketwiki" +config.formatting_engine_executeables = { + rocketwiki= "/opt/rocketwiki/rocketwiki-lqfb", + compat = "/opt/rocketwiki/rocketwiki-lqfb-compat" +} diff -r 768faea1096d -r 80c215dbf076 config/testing.lua --- a/config/testing.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/config/testing.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,3 +1,10 @@ execute.config("default") -config.wiki_parser_executeable = "/opt/liquid_feedback_testing/rocketwiki/rocketwiki" +config.formatting_engine_executeables = { + rocketwiki= "/opt/liquid_feedback_testing/rocketwiki/rocketwiki-lqfb", + compat = "/opt/liquid_feedback_testing/rocketwiki/rocketwiki-lqfb-compat" +} + +config.fastpath_url_func = function(member_id, image_type) + return "http://www.public-software-group.org/liquid_feedback_testing/fastpath/getpic?" .. tostring(member_id) .. "+" .. tostring(image_type) +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 env/format/wiki_text.lua --- a/env/format/wiki_text.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/env/format/wiki_text.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,6 +1,7 @@ -function format.wiki_text(wiki_text) +function format.wiki_text(wiki_text, formatting_engine) + local formatting_engine = formatting_engine or "rocketwiki" local html, errmsg, exitcode = assert( - os.pfilter(wiki_text, config.wiki_parser_executeable) + os.pfilter(wiki_text, config.formatting_engine_executeables[formatting_engine]) ) if exitcode > 0 then error("Wiki parser process returned with error code " .. tostring(exitcode)) diff -r 768faea1096d -r 80c215dbf076 env/ui/bargraph.lua --- a/env/ui/bargraph.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/env/ui/bargraph.lua Thu Dec 10 12:00:00 2009 +0100 @@ -6,7 +6,7 @@ content = function() for i, bar in ipairs(args.bars) do if bar.value > 0 then - local value = bar.value * args.width / args.max_value / 2 + local value = bar.value * args.width / args.max_value ui.container{ attr = { style = "width: " .. tostring(value) .. "px; background-color: " .. bar.color .. ";", diff -r 768faea1096d -r 80c215dbf076 env/ui/bargraph_legend.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/env/ui/bargraph_legend.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,32 @@ +function ui.bargraph_legend(attr) + local width = assert(attr.width) + local bars = assert(attr.bars) + + ui.container{ + attr = { class = "bargraph_legend" }, + content = function() + ui.container{ + attr = { class = "bargraph_legend_label" }, + content = _"Legend:" + } + for i, bar in ipairs(bars) do + ui.bargraph{ + max_value = 1, + width = width, + bars = { + { + color = bar.color, + value = 1, + } + } + } + ui.container{ + attr = { class = "bargraph_legend_label" }, + content = bar.label + } + end + end + } + + slot.put('
') +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 env/ui/tabs.lua --- a/env/ui/tabs.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/env/ui/tabs.lua Thu Dec 10 12:00:00 2009 +0100 @@ -23,6 +23,7 @@ text = tab.label, params = params } + slot.put(" ") end end } diff -r 768faea1096d -r 80c215dbf076 env/util/help.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/env/util/help.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,65 @@ +function util.help(id, title) + local setting_key = "liquidfeedback_frontend_hidden_help_" .. id + local setting = Setting:by_pk(app.session.member.id, setting_key) + if not setting then + ui.container{ + attr = { class = "help help_visible" }, + content = function() + ui.image{ + attr = { class = "help_icon" }, + static = "icons/16/help.png" + } + ui.container{ + attr = { class = "help_actions" }, + content = function() + ui.link{ + content = _"Hide this help message", + module = "help", + action = "update", + params = { + help_ident = id, + hide = true + }, + routing = { + default = { + mode = "redirect", + module = request.get_module(), + view = request.get_view(), + id = param.get_id_cgi(), + params = param.get_all_cgi() + } + } + } + end + } + local lang = locale.get("lang") + local basepath = request.get_app_basepath() + local file_name = basepath .. "/locale/help/" .. id .. "." .. lang .. ".txt" + local file = io.open(file_name) + if file ~= nil then + local help_text = file:read("*a") + if #help_text > 0 then + ui.container{ + attr = { class = "wiki" }, + content = function() + slot.put(format.wiki_text(help_text)) + end + } + else + ui.field.text{ value = _("Empty help text: #{id}.#{lang}.txt", { id = id, lang = lang }) } + end + else + ui.field.text{ value = _("Missing help text: #{id}.#{lang}.txt", { id = id, lang = lang }) } + end + end + } + else + if util._hidden_helps == nil then + util._hidden_helps = {} + end + util._hidden_helps[#util._hidden_helps+1] = { + id = id, + title = title + } + end +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 fastpath/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fastpath/Makefile Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,5 @@ +getpic: getpic.c + cc -g -Wall -o getpic getpic.c -I /usr/pkg/include/ -I /usr/include/postgresql -L /usr/pkg/lib -L /usr/lib/postgresql -lpq -Wl,-rpath,/usr/pkg/lib -Wl,-rpath,/usr/lib/postgresql + +clean:: + rm -f getpic diff -r 768faea1096d -r 80c215dbf076 fastpath/getpic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fastpath/getpic.c Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef GETPIC_CONNINFO +#define GETPIC_CONNINFO "dbname=liquid_feedback" +#endif + +#ifndef GETPIC_DEFAULT_AVATAR +#define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg" +#endif + +int main(int argc, const char * const *argv) { + PGconn *conn; + PGresult *dbr; + + char *cookies = getenv("HTTP_COOKIE"); + + char *args_string; + char *member_id; + char *image_type; + + char *sql_session_params[1]; + char *sql_member_image_params[2]; + + ssize_t start, length; + + char *session_ident; + + regex_t session_ident_regex; + regmatch_t session_ident_regmatch[2]; + + cookies = getenv("HTTP_COOKIE"); + + args_string = getenv("QUERY_STRING"); + + if (!cookies || !args_string) { + fputs("Status: 403 Access Denied\n\n", stdout); + return 0; + } + + member_id = strtok(args_string, "+"); + image_type = strtok(NULL, "+"); + + sql_member_image_params[0] = member_id; + sql_member_image_params[1] = image_type; + + // get session from cookie + + // TODO improve regex to fit better + if (regcomp(&session_ident_regex, "liquid_feedback_session=([a-zA-Z0-9]+)", REG_EXTENDED) != 0) { + // shouldn't happen + abort(); + } + + if (regexec(&session_ident_regex, cookies, 2, session_ident_regmatch, 0) != 0) { + fputs("Status: 403 Access Denied\n\n", stdout); + return 0; + } + + start = session_ident_regmatch[1].rm_so; + length = session_ident_regmatch[1].rm_eo - session_ident_regmatch[1].rm_so; + + session_ident = malloc(length + 1); + + strncpy(session_ident, cookies + start, length); + + session_ident[length] = 0; + + sql_session_params[0] = session_ident; + + + // connect to database + + conn = PQconnectdb(GETPIC_CONNINFO); + if (!conn) { + fputs("Could not create PGconn structure.\n", stderr); + return 1; + } + if (PQstatus(conn) != CONNECTION_OK) { + fputs(PQerrorMessage(conn), stderr); + return 1; + } + + // check session + dbr = PQexecParams(conn, + "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active", + 1, NULL, sql_session_params, NULL, NULL, 0 + ); + + if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { + fputs(PQresultErrorMessage(dbr), stderr); + return 1; + } + + if (PQntuples(dbr) != 1) { + fputs("Status: 403 Access Denied\n\n", stdout); + return 0; + } + + + // get picture + dbr = PQexecParams(conn, + "SELECT content_type, data " + "FROM member_image " + "WHERE member_id = $1 " + "AND image_type = $2 " + "AND scaled " + "LIMIT 1;", + 2, NULL, sql_member_image_params, NULL, NULL, 1 + ); + + if (PQresultStatus(dbr) != PGRES_TUPLES_OK) { + fputs(PQresultErrorMessage(dbr), stderr); + return 1; + } + if (PQntuples(dbr) > 1) { + return 1; + } + fputs("Cache-Control: private; max-age=86400\n", stdout); + if (PQntuples(dbr) == 0) { + struct stat sb; + PQclear(dbr); + PQfinish(conn); + fputs("Content-Type: image/jpeg\n\n", stdout); + if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1; + fprintf(stdout, "Content-Length: %i\n", sb.st_size); + execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL); + return 1; + } else { + if (PQnfields(dbr) < 0) { + fputs("Too few columns returned by database.\n", stderr); + return 1; + } + if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) { + fputs("Database did not return data in binary format.\n", stderr); + return 1; + } + if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) { + fputs("Unexpected NULL in database result.\n", stderr); + return 1; + } + fputs("Content-Type: ", stdout); + fprintf(stdout, "Content-Length: %i\n", PQgetlength(dbr, 0, 1)); + fwrite(PQgetvalue(dbr, 0, 0), PQgetlength(dbr, 0, 0), 1, stdout); + fputs("\n\n", stdout); + fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout); + } + PQclear(dbr); + PQfinish(conn); + return 0; +} diff -r 768faea1096d -r 80c215dbf076 locale/help/area.list.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/area.list.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,2 @@ +=Themenbereiche= +Die Balken zeigen dir an, wie hoch der Anteil der direkten Mitglieder bzw. der durch Delegation vertretenen Mitglieder des jeweiligen Themenbereichs im Verhältnis zur Gesamtzahl der Mitglieder dieses Systems ist. Für Testinitiativen (also Diskussionen, die nicht ernst gemeint sind) eignet sich übrigens der Themenbereich ,,Sandkasten/Spielwiese". diff -r 768faea1096d -r 80c215dbf076 locale/help/area.show.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/area.show.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,6 @@ +=Themenbereich, Mitgliedschaft= +Für die Teilnahme an der Diskussion und Endabstimmung einzelner Themen ist die Mitgliedschaft im Themenbereich **keine** Voraussetzung. Mit der Mitgliedschaft erklärst du vielmehr ein generelles Interesse an diesem Themenbereich. +=Delegation, Auto-Ablehnen= +Du kannst deine Stimme für diesen Themenbereich (unabhängig von deiner Mitgliedschaft im Themenbereich) an eine Person in deiner Kontaktliste delegieren. Als Themenbereichsmitglied kannst du ,,Auto-Ablehnen'' als Standardabstimmverhalten festlegen. Diese Weisung gilt nur für den Fall, dass du nicht selbst an der Endabstimmung teilnimmst, es keine tatsächlich genutzte Delegation und keine Weisung für das jeweilige konkrete Thema gibt. +=Neues Thema= +Hier kannst du mit einer eigenen Initiative ein neues Thema eröffnen. **Bevor** du ein neues Thema eröffnest, solltest du prüfen, ob es dieses Thema vieleicht schon gibt. Eine Initiative zu einem bestehenden Thema (Alternativantrag) kannst du von der jeweilige Themenseite aus starten. diff -r 768faea1096d -r 80c215dbf076 locale/help/contact.list.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/contact.list.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,4 @@ +=persönliche Kontaktliste= +Um sie schneller auffinden zu können, kannst du andere Mitglieder deiner persönlichen Kontaktliste hinzufügen. Auf der Profilseite des jeweiligen Mitglieds findest du einen Link zum Hinzufügen. Falls du einen Kontakt veröffentlichst, können andere sehen, dass dieses Mitglied auf deiner Kontaktliste steht. + +**Wichtig:** Zur Verbesserung des Bedienkomforts wird dir beim Delegieren deine persönliche Kontaktliste angezeigt. Um an ein Mitglied delegieren zu können, musst du es zunächst als Kontakt hinzufügen. Das Löschen eines Kontaktes führt jedoch nicht zum Widerruf der Delegation. diff -r 768faea1096d -r 80c215dbf076 locale/help/delegation.new.area.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/delegation.new.area.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,2 @@ +=Delegation für diesen Themenbereich= +Du kannst deine Stimme für diesen Themenbereich (unabhängig von deiner Mitgliedschaft im Themenbereich) an eine Person in deiner Kontaktliste delegieren. Diese Delegation hat gegenüber einer eventuell vorhandenen globalen Delegation Vorrang, gilt jedoch nur, wenn du dich nicht selbst beteiligst und für das jeweilige Thema keine themenspezifische Delegation erteilt hast. Für eine themenspezifische Delegation wechsele bitte auf die jeweilige Themenseite. Delegieren kannst du nur an Mitglieder in deiner Kontaktliste. Die Kontaktliste kannst du im Bereich ,,Mitglieder'' jederzeit erweitern. diff -r 768faea1096d -r 80c215dbf076 locale/help/delegation.new.global.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/delegation.new.global.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,2 @@ +=globale Delegation= +Die globale Delegation gilt immer dann, wenn du dich nicht selbst beteiligst und es keine Delegation auf der Ebene des jeweiligen Themenbereichs oder des Themas gibt. Delegieren kannst du nur an Mitglieder in deiner Kontaktliste. Die Kontaktliste kannst du im Bereich ,,Mitglieder'' jederzeit erweitern. diff -r 768faea1096d -r 80c215dbf076 locale/help/delegation.new.issue.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/delegation.new.issue.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,2 @@ +=Delegation für dieses Thema= +Eine Delegation zu diesem Thema geht einer eventuell vorhandenen globalen Delegation und/oder Delegation für den übergeordneten Themenbereich vor. Bei angemeldetem Interesse werden ausgehende Delegationen während der Diskussionsphase ausgesetzt, gelten aber in der Endabstimmung. Delegieren kannst du nur an Mitglieder in deiner Kontaktliste. Die Kontaktliste kannst du im Bereich ,,Mitglieder'' jederzeit erweitern. diff -r 768faea1096d -r 80c215dbf076 locale/help/index.change_password.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/index.change_password.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,2 @@ +=Kennwort ändern= +Dein neues Kennwort muss mindestens 8 Zeichen lang sein. diff -r 768faea1096d -r 80c215dbf076 locale/help/index.index.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/index.index.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,8 @@ +==Willkommen bei LiquidFeedback und auf deiner Startseite== +Diese blauen Boxen werden dich verfolgen bis du sie nach und nach abschaltest. Deine Startseite wird sich (hoffentlich) im Laufe der Zeit füllen: +- mit deinem Profil, +- den Themenbereichen, Themen und Initiativen die dich interessieren, +- deinen eingehenden und ausgehenden Delegationen, +- deinen veröffentlichten Kontakten. + +Und weil Neugier eine wichtige menschliche Eigenschaft ist, kannst du übrigens diese Informationen auch über die anderen Mitglieder abrufen. Wenn du wissen möchtest, ob deine Freunde schon im System sind, schau doch einfach mal unter ,,Mitglieder'' (ganz oben) nach. diff -r 768faea1096d -r 80c215dbf076 locale/help/initiative.show.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/initiative.show.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,10 @@ +=Initiative, Unterstützung, Anregungen= +Während der Diskussionsphase kannst du diese Initiative unterstützen und gibst damit den Initiatoren eine wichtige Rückmeldung, inwieweit der aktuelle Entwurf auf Zustimmung stößt. Darüber hinaus kannst du durch Anregungen (Änderungsvorschläge) mitteilen, was noch verbessert werden kann bzw. unter welchen Bedingungen du dir eine Unterstützung vorstellen kannst. + +Du kannst dich den Anregungen anderer Mitglieder anschließen (und damit das Gewicht dieser Anregungen erhöhen) und eigene (zusätzliche) Anregungen einbringen. Anregungen, die aus deiner Sicht unbedingt eingearbeitet werden müssen, damit du zustimmst, kennzeichnest du mit ,,muss'', wünschenswerte mit ,,soll''. Du kannst Anregungen auch kritisch gegenüber stehen und sie mit ,,soll nicht'' kennzeichnen. Eine Anregung, die bei Umsetzung zum Entzug deiner Zustimmung führen würde, kennzeichnest du mit ,,darf nicht''. +=überarbeiteter Entwurf, Umsetzungsvermerk= +Anhand der (klassifizierten und quantifizierten) Anregungen entscheiden die Initiatoren, was sie in einem neuen Entwurf besser dargestellen, ergänzen oder ändern. Der geänderte Entwurf wird den Unterstützern zur Bestätigung vorgelegt. Unterstützer können Anregungen als umgesetzt markieren, wenn die Anregung aus ihrer Sicht (hinreichend) umgesetzt wurde. Die einzelnen Unterstützer können diese Frage durchaus unterschiedlich beurteilen. +=wenn du nicht gehört wirst= +Wenn die Initiatoren deine Anregungen aus für dich nicht nachvollziehbaren Gründen nicht berücksichtigen, kannst du natürlich deine Änderungen in einer eigenen Initiative zur Diskussion stellen. +=wenn du diese Initiative ablehnst= +Wenn du diese Initiative grundsätzlich ablehnst, solltest du auf dieser Seite gar nichts machen, sondern die Initiative(n), der/denen du positiv gegenüber stehst, unterstützen und/oder deine eigene Initiative zu diesem Thema starten. diff -r 768faea1096d -r 80c215dbf076 locale/help/issue.show.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/issue.show.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,12 @@ +=Thema, Interesse= +Auf dieser Seite werden alle Initiativen zu diesem Thema aufgelistet. Wenn du ,,Interesse am Thema'' anmeldest, wirst du für dieses Thema den Mitgliedern des übergeordneten Themenbereichs gleichgestellt. Sobald du eine Initiative dieses Themas unterstützt, wird dein Interesse auch automatisch angemeldet. Sofern du allen Initiativen die Unterstützung entziehst, bleibt dein Interesse dennoch bestehen bis du es abmeldest. +=Delegation, Auto-Ablehnung= +Eine Delegation zu diesem Thema geht einer eventuell vorhandenen globalen Delegation und/oder Delegation für den übergeordneten Themenbereich vor. Eine eventuelle Weisung zur Auto-Ablehung gilt nur für den Fall, dass du nicht selbst an der Endabstimmung teilnimmst und es keine tatsächlich genutzte Delegation gibt. Bei angemeldetem Interesse werden ausgehende Delegationen während der Diskussionsphase ausgesetzt, gelten aber in der Endabstimmung. +=Diskussionsphase= +Während der Diskussionsphase (Zustände ,,Neu'' und ,,Diskussion'') solltest du **alle** Initiativen, die du grundsätzlich (oder unter bestimmten Bedingungen) für zustimmungsfähig hältst, unterstützen und Anregungen zur Verbesserung geben (Näheres dazu findest du auf der Initiativenseite). Hierdurch gibst du den Initiatoren die Chance, den Entwurf zu verbessern. Während dieser Phase hast du auch die Möglichkeit, eine eigene (konkurrierende) Initiative zu diesem Thema zu starten und um Unterstützung zu ringen. Deine Unterstützung für eine Initiative während der Diskussionsphase bedeutet keine Festlegung auf dein Verhalten in der Endabstimmung. +=Endabstimmung= +Initiativen, die ein bestimmtes Quorum erreichen, werden in die Endabstimmung übernommen. Du kannst dann alle Initiativen, denen du zustimmen möchtest, in eine Präferenzreihenfolge bringen. Bei den anderen Initiativen kannst Du dich enthalten oder auch dagegen stimmen (letzteres ebenfalls mit Präferenz). Beschlossen werden können nur Initiativen die insgesamt mehr Ja- als Nein-Stimmen erhalten. + +**Wichtig:** Es gibt keinen Grund mit Blick auf Mehrheitsverhältnisse (also aus Angst, deine Stimme zu ,,verschenken'') einen aus deiner Sicht suboptimalen Vorschlag vorzuziehen. Die Präferenzwahl führt (vereinfacht gesagt) dazu, dass sobald dein tatsächlicher Favorit nicht zum Zug kommt, deine Stimme voll für deinen ersten Ersatzwunsch zählt, danach für deinen zweiten Ersatzwunsch usw. + +Information zum genutzten Wahlverfahren: [http://en.wikipedia.org/wiki/Schulze_method Schulze-Methode] diff -r 768faea1096d -r 80c215dbf076 locale/help/member.edit.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/member.edit.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,2 @@ +=Profil= +Alle Angaben sind freiwillig. In Deinem Profil erscheinen nur die Felder, die nicht leer sind. diff -r 768faea1096d -r 80c215dbf076 locale/help/member.edit_images.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/member.edit_images.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,5 @@ +=Bilder= +Format: JPG +Avatar: max. 48 x 48 Pixel, für den Avatar bevorzugt ein quadratisches Bild +Foto: max. 250 x 250 Pixel +Größere Bilder werden herunterskaliert, alle Bilder werden recodiert und von Profilen befreit. diff -r 768faea1096d -r 80c215dbf076 locale/help/member.list.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/member.list.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,4 @@ +=Profilseiten aufrufen= +Hier kannst du die Profilseiten der einzelnen Mitglieder aufrufen und dich über ihre Beteiligung in Themenbereichen, an Themen und Initiativen informieren. Darüber hinaus werden dir ein- und ausgehende Delegationen und die veröffentlichten Kontakte des Mitglieds angezeigt. +=Kontaktliste erweitern= +Auf der Profilseite eines Mitglieds findest du auch einen Link, mit dem du das Mitglied zu deinen Kontakten hinzufügen kannst. Dies ist zum Beispiel erforderlich, wenn du deine Stimme an ein Mitglied delegieren möchtest. diff -r 768faea1096d -r 80c215dbf076 locale/help/member.show.de.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/locale/help/member.show.de.txt Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,9 @@ +=Profilseite= +Hier kannst du erfahren, +- was dieses Mitglied über sich selbst mitteilt, +- in welchen Themenbereichen es Mitglied ist, +- an welchen Themen und Initiativen es sich beteiligt +- welche Delegationen das Mitglied erhalten und erteilt und +- welche Kontakte das Mitglied veröffentlicht hat. +=zu den Kontakten hinzufügen= +Du kannst dieses Mitglied deiner Kontaktliste hinzufügen (und es natürlich auch wieder von dieser entfernen). Bitte beachte, dass du nur an Mitglieder delegieren kannst, die auf deiner Kontaktliste stehen. diff -r 768faea1096d -r 80c215dbf076 locale/motd/de.txt diff -r 768faea1096d -r 80c215dbf076 locale/translations.de.lua --- a/locale/translations.de.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/locale/translations.de.lua Thu Dec 10 12:00:00 2009 +0100 @@ -1,15 +1,15 @@ #!/usr/bin/env lua return { -["(change)"] = "(ändern)"; +["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht"; +["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert"; +["(change URL)"] = "(URL ändern)"; ["+ #{weight}"] = false; ["A-Z"] = false; ["About"] = false; ["About LiquidFeedback"] = "Über LiquidFeedback"; -["Accepted"] = "Akzeptiert"; +["Accepted at"] = "Angenommen am/um"; ["Active?"] = "Aktiv?"; -["Add my interest to this issue"] = "Mein Interesse am Thema anmelden"; -["Add my membership to this area"] = "Mitglied im Themenbereich werden"; -["Add new draft"] = "Neuen Entwurf hinzufügen"; +["Add my interest"] = "Mein Interesse anmelden"; ["Add new initiative to issue"] = "Neue Initiative zum Thema hinzufügen"; ["Add new suggestion"] = "Neue Anregung hinzufügen"; ["Add to my contacts"] = "Zu meinen Kontakten hinzufügen"; @@ -18,6 +18,7 @@ ["Admin menu"] = "Admin Menü"; ["Admin?"] = "Admin?"; ["Administrator"] = false; +["Admission time"] = "Zeit für die Zulassung"; ["Admitted"] = "zugelassen"; ["Any"] = "Alle"; ["Area"] = "Themenbereich"; @@ -25,18 +26,22 @@ ["Area delegation"] = "Area-Delegation"; ["Area list"] = "Liste der Themenbereiche"; ["Area successfully updated"] = "Themenbereich erfolgreich aktualisiert"; +["Area wide delegation active"] = "Delegation für Themengebiet aktiv"; ["Areas"] = "Themenbereiche"; ["Author"] = "Autor"; ["Autoreject is off."] = "Auto-Ablehnen ist aus"; ["Autoreject is on."] = "Auto-Ablehnen ist an"; ["Avatar"] = false; -["Avatar has been deleted"] = "Avatar wurde gelöscht"; -["Avatar has been updated"] = "Avatar wurde aktualisiert"; +["Become a member"] = "Mitglied werden"; ["Birthday"] = "Geburtstag"; +["Bug report"] = "Fehlerbericht"; ["Cancel"] = "Abbrechen"; ["Cancelled"] = "Abgebrochen"; +["Change area delegation"] = "Delegation für Themengebiet ändern"; +["Change global delegation"] = "Globale Delegation ändern"; +["Change issue delegation"] = "Delegation für Thema ändern"; ["Change password"] = "Kennwort ändern"; -["Click here to close."] = "Zum Schließen hier klicken"; +["Click for details"] = "Klicke für Details"; ["Close"] = "Schließen"; ["Closed"] = "geschlossen"; ["Collective opinion"] = "Meinungsbild"; @@ -50,37 +55,44 @@ ["Created at"] = "Erzeugt am/um"; ["Current draft"] = "Aktueller Entwurf"; ["Degree"] = "Grad"; -["Delegate"] = "Delegieren"; ["Delegations"] = "Delegationen"; ["Description"] = "Beschreibung"; ["Details"] = "Details"; ["Diff"] = false; ["Direct member count"] = "Anzahl Direktmitglieder"; -["Direct supporter [change]"] = "Direkte Unterstützung [ändern]"; +["Direct membership"] = "Direkte Mitgliedschaft"; ["Discussion"] = "Diskussion"; ["Discussion URL"] = "Diskussions-URL"; +["Discussion time"] = "Zeit für die Diskussions"; ["Draft"] = "Entwurf"; ["Edit"] = "Bearbeiten"; ["Edit draft"] = "Entwurf bearbeiten"; ["Edit initiative"] = "Initiative bearbeiten"; ["Edit my page"] = "Meine Seite bearbeiten"; +["Edit my profile"] = "Mein Profil bearbeiten"; +["Empty help text: #{id}.#{lang}.txt"] = false; ["Error while updating member, database reported:

(#{errormessage})"] = "Fehler beim aktualisieren des Mitglieds, die Datenbank berichtet folgenden Fehler:

(#{errormessage})"; -["External discussion"] = "Externe Diskussion"; ["External memberships"] = "Externe Mitgliedschaften"; ["External posts"] = "Externe Ämter"; ["Filter"] = false; ["Finished"] = "Abgeschlossen"; ["Frozen"] = "Eingefroren"; ["Fulfilled"] = "Erfüllt"; -["Fully frozen"] = "Ganz eingefroren"; +["Fully frozen at"] = "Ganz eingefroren am/um"; ["Global delegation"] = "Globale Delegation"; -["Half frozen"] = "Halb eingefroren"; +["Global delegation active"] = "Globale Delegation aktiv"; +["Half frozen at"] = "Halb eingefroren am/um"; +["Help for: #{text}"] = "Hilfe zu: #{text}"; ["Hide"] = "Verstecken"; +["Hide this help message"] = "Diesen Hilfetext ausblenden"; ["Home"] = "Startseite"; ["Id"] = "Id"; ["Ident number"] = "Ident-Nummer"; +["Images"] = "Bilder"; ["In discussion"] = "In Diskussion"; ["Incoming delegations"] = "Eingehende Delegationen"; +["Initiated initiatives"] = "Initierte Initiativen"; +["Initiative quorum"] = "Quorum Inititive"; ["Initiative successfully created"] = "Initiative erfolgreich erzeugt"; ["Initiative successfully updated"] = "Initiative erfolgreich aktualisiert"; ["Initiative: '#{name}'"] = "Initiative: '#{name}'"; @@ -96,12 +108,14 @@ ["Issue ##{id}"] = "Issue ##{id}"; ["Issue ##{id} (#{policy_name})"] = "Thema ##{id} (#{policy_name})"; ["Issue delegation"] = "Issue-Delegation"; +["Issue delegation active"] = "Delegation für Thema aktiv"; ["Issue policy"] = "Regelwerk für Thema"; +["Issue quorum"] = "Quorum Thema"; ["Issues"] = "Themen"; ["Last snapshot:"] = "Letzte Auszählung:"; +["Legend:"] = "Legende:"; ["License"] = "Lizenz"; ["Locked?"] = "Gesperrt?"; -["Logged in as:"] = "Angemeldet als:"; ["Login"] = "Anmeldung"; ["Login successful!"] = "Anmeldung erfolgreich"; ["Logout"] = "Abmelden"; @@ -119,13 +133,17 @@ ["Member list"] = "Mitgliederliste"; ["Member login"] = "Mitglied Login"; ["Member name"] = "Mitglied Name"; +["Member page"] = false; ["Member successfully registered"] = "Mitglied erfolgreich registriert"; ["Member successfully updated"] = "Mitglied erfolgreich aktualisert"; ["Member: '#{login}' (#{name})"] = "Mitlied: '#{login}' (#{name})"; ["Members"] = "Mitglieder"; +["Membership by delegation"] = "Mitgliedschaft durch Delegation"; ["Membership not existant"] = "Mitgliedschaft exisitert nicht"; ["Membership removed"] = "Mitgliedschaft entfernt"; ["Membership updated"] = "Mitgliedschaft aktualisiert"; +["Memberships"] = "Mitgliedschaften"; +["Missing help text: #{id}.#{lang}.txt"] = false; ["Mobile phone"] = "Mobiltelefon"; ["My opinion"] = "Meine Meinung"; ["Name"] = "Name"; @@ -137,7 +155,9 @@ ["New passwords is too short."] = "Das neue Kennwort ist zu kurz"; ["Newest"] = "Neueste"; ["Next state"] = "Nächster Zustand"; -["No supporter [change]"] = "Keine Unterstützung (ändern)"; +["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert"; +["No delegation"] = "Keine Delegation"; +["No membership at all"] = "Gar keine Mitgliedschaft"; ["Number of incoming delegations, follow link to see more details"] = "Anzahl eingehender Delegationen, Link folgen für mehr Details"; ["OK"] = "OK"; ["Old draft revision"] = "Alte Revision des Entwurfs"; @@ -150,9 +170,12 @@ ["Outgoing delegations"] = "Ausgehende Delegationen"; ["Password"] = "Kennwort"; ["Phone"] = "Telefon"; +["Photo"] = "Foto"; ["Policy"] = "Regelwerk"; ["Population"] = "Grundgesamtheit"; +["Posts"] = "Ämter"; ["Profession"] = "Beruf"; +["Profile"] = "Profil"; ["Publish"] = "Veröffentlichen"; ["Published"] = "veröffentlicht"; ["Published contacts"] = "Veröffentlichte Kontakte"; @@ -176,9 +199,12 @@ ["Search issues"] = "Suche Themen"; ["Search members"] = "Suche Mitglieder"; ["Search results for: '#{search}'"] = "Suchergebnisse für: '#{search}'"; +["Set area delegation"] = "Delegation für Themengebiet festlegen"; ["Set autoreject"] = "Auto-Ablehnen anschalten"; ["Set delegation for Area '#{name}'"] = "Delegation für Themengebiet '#{name}' festlegen"; ["Set delegation for Issue ##{number} in Area '#{area_name}'"] = "Delegation für Thema ##{number} im Themenbereich '#{area_name}' festlegen"; +["Set global delegation"] = "Globale Delegation festlegen"; +["Set issue delegation"] = "Delegation für Thema festlegen"; ["Show"] = "Zeige"; ["Show active members"] = "Zeige aktive Mitglieder"; ["Show areas in use"] = "Zeige verwendete Themenbereiche"; @@ -186,6 +212,7 @@ ["Show diff"] = "Änderungen anzeigen"; ["Show locked members"] = "Zeige gesperrte Mitglieder"; ["Show member"] = "Mitglied anzeigen"; +["Show other initiatives"] = "Zeige alternative Initiativen"; ["Software"] = false; ["State"] = "Zustand"; ["Statement"] = false; @@ -197,31 +224,34 @@ ["Support"] = "Unterstützung"; ["Support S+I"] = "Unterstütung S+I"; ["Support this initiative"] = "Diese Initiative unterstützen"; +["Supported initiatives"] = "Unterstützte Initiativen"; ["Supporter"] = "Unterstützer"; ["That's me!"] = "Das bin ich"; ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht"; ["Time left"] = "Restzeit"; +["Title (80 chars max)"] = "Titel (max. 80 Zeichen)"; ["Trustee"] = "Bevollmächtigter"; ["Unknown author"] = "Unbekannter Autor"; -["Upload avatar"] = "Avatar hochladen"; +["Upload images"] = "Bilder hochladen"; ["Username"] = "Benutzername"; +["Verification time"] = "Zeit für die Überprüfung"; ["Version"] = false; ["Vote later"] = "Später abstimmen"; ["Vote now"] = "Jetzt abstimmen"; ["Voting"] = "Abstimmung"; ["Voting requests"] = "Abstimmanträge"; +["Voting time"] = "Zeit für die Abstimmung"; ["Website"] = "Webseite"; -["X"] = false; ["You are already not supporting this initiative"] = "Diese Initiative hat bereits keine Unterstützung von Dir"; ["You are already supporting the latest draft"] = "Du unterstützt bereits den neuesten Entwurf"; -["You are interested. [more]"] = "Du bist interessiert. [mehr]"; -["You are member. [more]"] = "Du bist Mitglied. [mehr]"; -["You are not a member. [more]"] = "Du bist kein Mitglied. [mehr]"; -["You are not interested. [more]"] = "Du bist nicht interessiert. [mehr]"; +["You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."] = false; +["You are member"] = "Du bist Mitglied"; ["You didn't saved any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!"; ["You have saved this member as contact"] = "Du hast das Mitglied als Kontakt gespeichert"; ["You have saved this member as contact."] = "Du hast das Mitglied als Kontakt gespeichert."; ["You need to be logged in, to use this system."] = "Du musst eingeloggt sein, um das System zu benutzen"; +["Your are interested"] = "Du bist interessiert"; +["Your are supporter"] = "Du bist Unterstützer"; ["Your delegation for this area has been deleted."] = "Deine Delegation für dieses Themengebiet wurde gelöscht"; ["Your delegation for this area has been updated."] = "Deine Delegation für dieses Themengebiet wurde geändert"; ["Your delegation for this issue has been deleted."] = "Deine Delegation für dieses Thema wurde gelöscht"; @@ -236,23 +266,18 @@ ["Your support has been added to this initiative"] = "Deine Unterstützung wurde der Initiative hinzugefügt"; ["Your support has been removed from this initiative"] = "Deine Unterstützung wurde der Initiave entzogen"; ["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert"; -["Your vote is delegated. [more]"] = "Deine Stimme ist delegiert. [mehr]"; ["Z-A"] = false; -["admission_time"] = false; +["all"] = "Alle"; ["blank"] = false; -["delete

"] = false; -["discussion_time"] = false; +["delete

"] = "löschen

"; ["email"] = false; -["initiative_quorum_den"] = false; -["initiative_quorum_num"] = false; -["issue_quorum_den"] = false; -["issue_quorum_num"] = false; ["must"] = "muss"; ["must not"] = "darf nicht"; +["must/should"] = "muss/soll"; +["must/should not"] = "muss/soll nicht"; ["neutral"] = "neutral"; +["not implemented"] = "nicht umgesetzt"; ["should"] = "soll"; ["should not"] = "soll nicht"; -["verification_time"] = false; -["voting_time"] = false; ["xmpp"] = false; } diff -r 768faea1096d -r 80c215dbf076 model/initiative.lua --- a/model/initiative.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/model/initiative.lua Thu Dec 10 12:00:00 2009 +0100 @@ -26,7 +26,6 @@ that_key = 'initiative_id', ref = 'suggestions', back_ref = 'initiative', - default_order = '"id"' } Initiative:add_reference{ diff -r 768faea1096d -r 80c215dbf076 model/member.lua --- a/model/member.lua Mon Nov 30 12:00:00 2009 +0100 +++ b/model/member.lua Thu Dec 10 12:00:00 2009 +0100 @@ -2,11 +2,11 @@ Member.table = 'member' Member:add_reference{ - mode = '11', + mode = '1m', to = "MemberImage", this_key = 'id', that_key = 'member_id', - ref = 'image', + ref = 'images', back_ref = 'member' } diff -r 768faea1096d -r 80c215dbf076 model/setting.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/model/setting.lua Thu Dec 10 12:00:00 2009 +0100 @@ -0,0 +1,17 @@ +Setting = mondelefant.new_class() +Setting.table = 'setting' +Setting.primary_key = { "member_id", "key" } +Interest:add_reference{ + mode = 'm1', + to = "Member", + this_key = 'member_id', + that_key = 'id', + ref = 'member', +} + +function Setting:by_pk(member_id, key) + return self:new_selector() + :add_where{ "member_id = ? AND key = ?", member_id, key } + :optional_object_mode() + :exec() +end \ No newline at end of file diff -r 768faea1096d -r 80c215dbf076 static/icons/16/book_delete.png Binary file static/icons/16/book_delete.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/bug.png Binary file static/icons/16/bug.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/dropdown.png Binary file static/icons/16/dropdown.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/error.png Binary file static/icons/16/error.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/help.png Binary file static/icons/16/help.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/lightning.png Binary file static/icons/16/lightning.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/user_add.png Binary file static/icons/16/user_add.png has changed diff -r 768faea1096d -r 80c215dbf076 static/icons/16/user_green.png Binary file static/icons/16/user_green.png has changed diff -r 768faea1096d -r 80c215dbf076 static/style.css --- a/static/style.css Mon Nov 30 12:00:00 2009 +0100 +++ b/static/style.css Thu Dec 10 12:00:00 2009 +0100 @@ -60,31 +60,27 @@ .layout_notice, .layout_error, .layout_warning { background: #fff; font-weight: bold; - right: 2ex; line-height: 1.7em; - position: absolute; - top: 6ex; - width: 60ex; -moz-opacity:0.7; } .slot_notice, .slot_warning, .slot_error { - padding: 2ex; + padding-left: 1em; } .slot_notice { - color: green; - border: 2px solid green; + background-color: #cfc; + color: #040; } .slot_warning { - color: orange; - border: 2px solid orange; + background-color: #fec; + color: #420; } .slot_error { - color: red; - border: 2px solid red; + background-color: #fcc; + color: #400; } /************************************************************************* @@ -92,7 +88,6 @@ */ .topbar { - margin-bottom: 1em; background-color: #444; color: #fff; font-size: 75%; @@ -161,17 +156,21 @@ */ .title_bar { - border-bottom: 1px solid #000; + border-bottom: 1px solid #777; margin-bottom: 2ex; + padding-top: 1ex; + padding-bottom: 0.5ex; +} + +.title_bar_content { + margin-left: 1em; } .path { color: #444; - xbackground-color: #ddd; } .path div { - margin-left: 1em; font-size: 100%; line-height: 180%; } @@ -195,7 +194,6 @@ } .title div { - margin-left: 0.66em; font-weight: bold; font-size: 135%; line-height: 110%; @@ -205,25 +203,23 @@ color: #fff; } -.avatar { +.member_image_avatar { float: left; margin-right: 0.5em; - width: 48px; - height: 48px; } .actions { - display: inline; font-size: 75%; - line-height: 200%; + line-height: 220%; } .slot_actions { - margin-left: 1em; display: inline; } .actions a { + float: left; + display: block; padding: 0.5ex 0.5em 0.5ex 0.0em; margin-right: 1em; vertical-align: middle; @@ -236,37 +232,70 @@ .actions img { padding-left: 0.2em; padding-right: 0.2em; + vertical-align: middle; +} + +.logo { + float: right; + margin-right: 1em; } /************************************************************************* * vote info / delegation */ -.slot_interest, +.interest, .slot_support, -.slot_delegation { +.delegation { float: left; - font-size: 75%; + position: relative; +} + +.interest img, +.slot_support img, +.delegation img { + padding-left: 0.2em; + padding-right: 0.2em; +} +.vote_info .head { + float: left; margin-right: 1em; } -.vote_info .head { - line-height: 200%; +.interest .head_active { + background-color: #dfd; + border: 1px solid #8b8; +} + +.slot_support .head_active { + background-color: #dfd; + border: 1px solid #8b8; +} + +.delegation .head_active { + background-color: #ffd; + border: 1px solid #bb8; } .vote_info .close { - background-color: #f44; - float: right; + position: absolute; + top: 0; + right: 0; padding: 1ex; + display: block; } .vote_info .content { + font-size: 133%; + line-height: 100%; + top: 3ex; display: none; position: absolute; z-index: 10; background-color: #fff; - border: 2px solid #444; + border: 1px solid #999; padding: 1em; + width: 25em; } .vote_info .delegation_arrow { @@ -275,6 +304,14 @@ vertical-align: middle; } +.vote_info .delegation_arrow_overridden { + opacity: 0.4; +} + +.vote_info .delegation_scope_overridden { + color: #777; +} + .vote_info .delegation_scope { display: inline; } @@ -286,14 +323,29 @@ clear: left; } +.delegation_overridden .member_thumb { + opacity: 0.4; +} + .delegation .revoke { margin: 0.5ex; + float: right; } .delegation .revoke img { vertical-align: middle; } + +.sub_title div { + border-top: 1px solid #444; + padding-top: 1ex; + margin-top: 1ex; + font-weight: bold; + font-size: 135%; + line-height: 110%; +} + /************************************************************************* * Main content */ @@ -315,8 +367,9 @@ .ui_tabs_links a { padding: 1ex; - margin-left: 0.5em; + line-height: 200%; background-color: #e7e7e7; + white-space: nowrap; } .ui_tabs_links a:hover { @@ -401,6 +454,25 @@ height: 1.3ex; } +.bargraph_legend { + margin-top: 2ex; +} + +.bargraph_legend .bargraph { + width: 26px; +} + +.bargraph_legend div, +.bargraph_legend div div, +.bargraph_legend div div div { + float: left; +} + +.bargraph_legend_label { + margin-left: 0.5em; + margin-right: 1em; +} + /************************************************************************* * vertical ui.form */ @@ -432,7 +504,7 @@ .vertical .ui_field_label { text-transform: uppercase; font-size: 70%; - line-height: 190%; + line-height: 120%; font-weight: bold; color: #777; width: 15em; @@ -631,10 +703,22 @@ .member_thumb { text-decoration: none; - min-width: 150px; + width: 18em; + height: 48px; display: block; float: left; - border: 1px solid #ccc; + border: 1px solid #999; + overflow: hidden; + xwhite-space: nowrap; + position: relative; +} + +.member_thumb a{ + position: absolute; + top: 0; + left: 0; + padding: 0; + margin: 0; } .member_thumb a:hover div { @@ -642,25 +726,24 @@ color: #fff; } -.member_thumb .flags a:hover { - background-color: #444; - color: #fff; -} - .member_thumb img { - margin-right: 0.5em; + padding: 0; + margin: 0; vertical-align: bottom; - float: left; } .member_thumb div { - display: inline; +} + +.member_thumb .member_image { } .member_thumb .member_name { - display: block; - margin-top: 3ex; - margin-right: 0.5em; + position: absolute; + left: 48px; + top: 2ex; + font-size: 100%; + width: 14em; } .member_thumb .flags { @@ -668,10 +751,22 @@ font-size: 75%; } -.draft_content { +.member_thumb .flags a{ + position: static; + float: right; +} + + +.member .right { + float: right; +} + +.draft_content, +.member_statement { background-color: #eee; border: 1px solid #ccc; - padding: 1ex; + padding-left: 1ex; + padding-right: 1ex; } .diff { @@ -715,3 +810,73 @@ padding: 1ex; } +.suggestion_fulfilled { + width: 15em; +} +.suggestion_fulfilled a.action { + padding-left: 0; + line-height: 120%; +} + +.help { + border: 1px solid #bcd; + background-color: #def; + color: #000; + padding: 1ex; +} + +.help_visible { + margin-bottom: 1ex; +} + +.help_visible .help_icon { + float: right; +} + +.slot_help_hidden { + float: right; + margin-right: 1em; +} + +.help_actions { + font-size: 75%; + float: right; +} + +.help_actions a { + margin-right: 1em; + color: #468; +} + +.wiki { +} + +.wiki h1, +.wiki h2, +.wiki h3, +.wiki h4 { + margin-top: 1ex; + margin-bottom: 1ex; +} + +.wiki h1 { + font-size: 150%; +} + +.wiki h2 { + font-size: 125%; +} + +.wiki p { + margin-top: 1ex; + margin-bottom: 1ex; +} + +form .warning { + background-color: #ffd; + color: #000; + border: 1px solid #dda; + margin: 1ex; + margin-bottom: 2ex; + padding: 1ex; +}