liquid_feedback_frontend

changeset 4:80c215dbf076 alpha5

Version alpha5

Many optical changes and improved usability

Support for different wiki-formatting-engines

Help system
author bsw/jbe
date Thu Dec 10 12:00:00 2009 +0100 (2009-12-10)
parents 768faea1096d
children afd9f769c7ae
files app/main/_filter_view/30_navigation.lua app/main/_filter_view/33_help_hidden.lua app/main/_layout/default.html app/main/area/_action/update.lua app/main/area/_list.lua app/main/area/list.lua app/main/area/show.lua app/main/contact/_list.lua app/main/contact/list.lua app/main/delegation/_action/update.lua app/main/delegation/_show_box.lua app/main/delegation/new.lua app/main/draft/_action/add.lua app/main/draft/_show.lua app/main/draft/new.lua app/main/help/_action/update.lua app/main/index/_action/set_lang.lua app/main/index/change_password.lua app/main/index/index.lua app/main/initiative/_action/create.lua app/main/initiative/_list.lua app/main/initiative/edit.lua app/main/initiative/new.lua app/main/initiative/show.lua app/main/interest/_show_box.lua app/main/issue/_show_head.lua app/main/issue/show.lua app/main/member/_action/update_avatar.lua app/main/member/_action/update_images.lua app/main/member/_show.lua app/main/member/_show_thumb.lua app/main/member/_show_thumb.lua.orig app/main/member/avatar.lua app/main/member/edit.lua app/main/member/edit_avatar.lua app/main/member/edit_images.lua app/main/member/list.lua app/main/member/show.lua app/main/member_image/_show.lua app/main/member_image/show.lua app/main/membership/_action/update.lua app/main/membership/_show_box.lua app/main/suggestion/_list.lua app/main/suggestion/show.lua app/main/supporter/_show_box.lua app/main/supporter/show_incoming.lua config/default.lua config/development.lua config/testing.lua env/format/wiki_text.lua env/ui/bargraph.lua env/ui/bargraph_legend.lua env/ui/tabs.lua env/util/help.lua fastpath/Makefile fastpath/getpic.c locale/help/area.list.de.txt locale/help/area.show.de.txt locale/help/contact.list.de.txt locale/help/delegation.new.area.de.txt locale/help/delegation.new.global.de.txt locale/help/delegation.new.issue.de.txt locale/help/index.change_password.de.txt locale/help/index.index.de.txt locale/help/initiative.show.de.txt locale/help/issue.show.de.txt locale/help/member.edit.de.txt locale/help/member.edit_images.de.txt locale/help/member.list.de.txt locale/help/member.show.de.txt locale/motd/de.txt locale/translations.de.lua model/initiative.lua model/member.lua model/setting.lua static/icons/16/book_delete.png static/icons/16/bug.png static/icons/16/dropdown.png static/icons/16/error.png static/icons/16/help.png static/icons/16/lightning.png static/icons/16/user_add.png static/icons/16/user_green.png static/style.css
line diff
     1.1 --- a/app/main/_filter_view/30_navigation.lua	Mon Nov 30 12:00:00 2009 +0100
     1.2 +++ b/app/main/_filter_view/30_navigation.lua	Thu Dec 10 12:00:00 2009 +0100
     1.3 @@ -71,6 +71,15 @@
     1.4        view = 'about'
     1.5      }
     1.6  
     1.7 +    ui.link{
     1.8 +      content = function()
     1.9 +        ui.image{ static = "icons/16/bug.png" }
    1.10 +        slot.put(_'Bug report')
    1.11 +      end,
    1.12 +      external = "http://trac.public-software-group.org/projects/lf" --/newticket?description=" .. encode.url_part("\n\n\n\nReport for: " .. os.getenv("REQUEST_URI") )
    1.13 +    }
    1.14 +
    1.15 +
    1.16    if app.session.member.admin then
    1.17  
    1.18      slot.put(" ")
    1.19 @@ -89,6 +98,12 @@
    1.20  
    1.21  end)
    1.22  
    1.23 +if config.app_logo then
    1.24 +  slot.select("logo", function()
    1.25 +    ui.image{ static = config.app_logo }
    1.26 +  end)
    1.27 +end
    1.28 +
    1.29  execute.inner()
    1.30  
    1.31  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/app/main/_filter_view/33_help_hidden.lua	Thu Dec 10 12:00:00 2009 +0100
     2.3 @@ -0,0 +1,36 @@
     2.4 +execute.inner()
     2.5 +
     2.6 +if util._hidden_helps ~= nil then
     2.7 +  slot.select("help_hidden", function()
     2.8 +    for i, help in ipairs(util._hidden_helps) do 
     2.9 +      ui.link{
    2.10 +        attr = {
    2.11 +          class = "help_hidden",
    2.12 +          title = _("Help for: #{text}", { text = help.title })
    2.13 +        },
    2.14 +        module = "help",
    2.15 +        action = "update",
    2.16 +        params = {
    2.17 +          help_ident = help.id,
    2.18 +          hide = false
    2.19 +        },
    2.20 +        routing = {
    2.21 +          default = {
    2.22 +            mode = "redirect",
    2.23 +            module = request.get_module(),
    2.24 +            view = request.get_view(),
    2.25 +            id = param.get_id_cgi(),
    2.26 +            params = param.get_all_cgi()
    2.27 +          }
    2.28 +        },
    2.29 +        content = function()
    2.30 +          ui.image{
    2.31 +            attr = { class = "help_icon" },
    2.32 +            static = "icons/16/help.png"
    2.33 +          }
    2.34 +        end
    2.35 +      }
    2.36 +    end
    2.37 +  end)
    2.38 +end
    2.39 +
     3.1 --- a/app/main/_layout/default.html	Mon Nov 30 12:00:00 2009 +0100
     3.2 +++ b/app/main/_layout/default.html	Thu Dec 10 12:00:00 2009 +0100
     3.3 @@ -18,29 +18,47 @@
     3.4          <!-- WEBMCP SLOT navigation -->
     3.5        </div>
     3.6      </div>
     3.7 +    <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';">
     3.8 +      <!-- WEBMCP SLOT notice -->
     3.9 +    </div>
    3.10 +    <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';">
    3.11 +      <!-- WEBMCP SLOT warning -->
    3.12 +    </div>
    3.13 +    <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';">
    3.14 +      <!-- WEBMCP SLOT error -->
    3.15 +    </div>
    3.16      <div class="title_bar">
    3.17 -      <div class="issue_info" id="issue_info">
    3.18 -        <!-- WEBMCP SLOT issue_info -->
    3.19 -      </div>
    3.20 -      <div class="path" id="path">
    3.21 -        <!-- WEBMCP SLOT path -->
    3.22 -      </div>
    3.23 -      <div class="title" id="title">
    3.24 -        <!-- WEBMCP SLOT title -->
    3.25 +      <div class="title_bar_content">
    3.26 +        <div class="logo" id="logo">
    3.27 +          <!-- WEBMCP SLOT logo -->
    3.28 +        </div>
    3.29 +        <div class="issue_info" id="issue_info">
    3.30 +          <!-- WEBMCP SLOT issue_info -->
    3.31 +        </div>
    3.32 +        <div class="path" id="path">
    3.33 +          <!-- WEBMCP SLOT path -->
    3.34 +        </div>
    3.35 +        <div class="title" id="title">
    3.36 +          <!-- WEBMCP SLOT title -->
    3.37 +        </div>
    3.38 +        <div class="help_hidden" id="help_hidden">
    3.39 +          <!-- WEBMCP SLOT help_hidden -->
    3.40 +        </div>
    3.41 +        <div class="actions" id="actions">
    3.42 +          <div class="interest vote_info" id="interest">
    3.43 +            <!-- WEBMCP SLOT interest -->
    3.44 +          </div>
    3.45 +          <!-- WEBMCP SLOT actions -->
    3.46 +        </div>
    3.47 +        <br style="clear: left;" />
    3.48 +        <div class="sub_title" id="sub_title">
    3.49 +          <!-- WEBMCP SLOT sub_title -->
    3.50 +        </div>
    3.51 +        <div class="support vote_info" id="support">
    3.52 +          <!-- WEBMCP SLOT support -->
    3.53 +        </div>
    3.54 +        <div style="clear: left;" /></div>
    3.55        </div>
    3.56 -      <div class="interest vote_info" id="interest">
    3.57 -        <!-- WEBMCP SLOT interest -->
    3.58 -      </div>
    3.59 -      <div class="support vote_info" id="support">
    3.60 -        <!-- WEBMCP SLOT support -->
    3.61 -      </div>
    3.62 -      <div class="delegation vote_info" id="delegation">
    3.63 -        <!-- WEBMCP SLOT delegation -->
    3.64 -      </div>
    3.65 -      <div class="actions" id="actions">
    3.66 -        <!-- WEBMCP SLOT actions -->
    3.67 -      </div>
    3.68 -      <br style="clear: left;" />
    3.69      </div>
    3.70      <div class="main" id="default">
    3.71        <!-- WEBMCP SLOT default -->
    3.72 @@ -55,15 +73,6 @@
    3.73          </div>
    3.74        </div>
    3.75      </div>
    3.76 -    <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';">
    3.77 -      <!-- WEBMCP SLOT notice -->
    3.78 -    </div>
    3.79 -    <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';">
    3.80 -      <!-- WEBMCP SLOT warning -->
    3.81 -    </div>
    3.82 -    <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';">
    3.83 -      <!-- WEBMCP SLOT error -->
    3.84 -    </div>
    3.85    </body>
    3.86    <script>
    3.87    </script>
     4.1 --- a/app/main/area/_action/update.lua	Mon Nov 30 12:00:00 2009 +0100
     4.2 +++ b/app/main/area/_action/update.lua	Thu Dec 10 12:00:00 2009 +0100
     4.3 @@ -1,3 +1,7 @@
     4.4 +if not app.session.member.admin then
     4.5 +  error()
     4.6 +end
     4.7 +
     4.8  local id = param.get_id()
     4.9  
    4.10  local area
     5.1 --- a/app/main/area/_list.lua	Mon Nov 30 12:00:00 2009 +0100
     5.2 +++ b/app/main/area/_list.lua	Thu Dec 10 12:00:00 2009 +0100
     5.3 @@ -35,7 +35,7 @@
     5.4                local max_value = MemberCount:get()
     5.5                ui.bargraph{
     5.6                  max_value = max_value,
     5.7 -                width = 200,
     5.8 +                width = 100,
     5.9                  bars = {
    5.10                    { color = "#444", value = record.direct_member_count },
    5.11                    { color = "#777", value = record.member_weight - record.direct_member_count },
    5.12 @@ -58,4 +58,14 @@
    5.13        }
    5.14      }
    5.15    end
    5.16 -}
    5.17 \ No newline at end of file
    5.18 +}
    5.19 +
    5.20 +ui.bargraph_legend{
    5.21 +  width = 25,
    5.22 +  bars = {
    5.23 +    { color = "#444", label = _"Direct membership" },
    5.24 +    { color = "#777", label = _"Membership by delegation" },
    5.25 +    { color = "#ddd", label = _"No membership at all" },
    5.26 +  }
    5.27 +}
    5.28 +
     6.1 --- a/app/main/area/list.lua	Mon Nov 30 12:00:00 2009 +0100
     6.2 +++ b/app/main/area/list.lua	Thu Dec 10 12:00:00 2009 +0100
     6.3 @@ -1,5 +1,7 @@
     6.4  slot.put_into("title", _'Area list')
     6.5  
     6.6 +util.help("area.list", _"Area list")
     6.7 +
     6.8  local areas_selector = Area:new_selector():add_where("active")
     6.9  
    6.10  execute.view{
    6.11 @@ -8,7 +10,9 @@
    6.12    params = { areas_selector = areas_selector }
    6.13  }
    6.14  
    6.15 +--[[
    6.16  execute.view{
    6.17    module = "delegation",
    6.18    view = "_show_box"
    6.19 -}
    6.20 \ No newline at end of file
    6.21 +}
    6.22 +--]]
     7.1 --- a/app/main/area/show.lua	Mon Nov 30 12:00:00 2009 +0100
     7.2 +++ b/app/main/area/show.lua	Thu Dec 10 12:00:00 2009 +0100
     7.3 @@ -13,15 +13,6 @@
     7.4  slot.select("actions", function()
     7.5    ui.link{
     7.6      content = function()
     7.7 -      ui.image{ static = "icons/16/table_go.png" }
     7.8 -      slot.put(_"Delegate")
     7.9 -    end,
    7.10 -    module = "delegation",
    7.11 -    view = "new",
    7.12 -    params = { area_id = area.id }
    7.13 -  }
    7.14 -  ui.link{
    7.15 -    content = function()
    7.16        ui.image{ static = "icons/16/folder_add.png" }
    7.17        slot.put(_"Create new issue")
    7.18      end,
    7.19 @@ -31,6 +22,8 @@
    7.20    }
    7.21  end)
    7.22  
    7.23 +util.help("area.show")
    7.24 +
    7.25  execute.view{
    7.26    module = "membership",
    7.27    view = "_show_box",
     8.1 --- a/app/main/contact/_list.lua	Mon Nov 30 12:00:00 2009 +0100
     8.2 +++ b/app/main/contact/_list.lua	Thu Dec 10 12:00:00 2009 +0100
     8.3 @@ -2,7 +2,7 @@
     8.4  local contacts_selector = Contact:new_selector()
     8.5    :add_where{ "member_id = ?", app.session.member.id }
     8.6    :join("member", nil, "member.id = contact.other_member_id")
     8.7 -  :add_order_by("member.login")
     8.8 +  :add_order_by("member.name")
     8.9  
    8.10  ui.paginate{
    8.11    selector = contacts_selector,
    8.12 @@ -15,17 +15,6 @@
    8.13          records = contacts,
    8.14          columns = {
    8.15            {
    8.16 -            label = _"Login",
    8.17 -            content = function(record)
    8.18 -              ui.link{
    8.19 -                text = record.other_member.login,
    8.20 -                module = "member",
    8.21 -                view = "show",
    8.22 -                id = record.other_member_id
    8.23 -              }
    8.24 -            end
    8.25 -          },
    8.26 -          {
    8.27              label = _"Name",
    8.28              content = function(record)
    8.29                ui.link{
    8.30 @@ -103,30 +92,8 @@
    8.31                }
    8.32              end
    8.33            },
    8.34 -          {
    8.35 -            content = function(record)
    8.36 -              ui.link{
    8.37 -                attr = { class = "action" },
    8.38 -                text = _"Global delegation",
    8.39 -                module = "delegation",
    8.40 -                action = "update",
    8.41 -                params = { 
    8.42 -                  trustee_id = record.other_member_id,
    8.43 -                },
    8.44 -                routing = {
    8.45 -                  default = {
    8.46 -                    mode = "redirect",
    8.47 -                    module = request.get_module(),
    8.48 -                    view = request.get_view(),
    8.49 -                    id = param.get_id_cgi(),
    8.50 -                    params = param.get_all_cgi()
    8.51 -                  }
    8.52 -                }
    8.53 -              }
    8.54 -            end
    8.55 -          }
    8.56          }
    8.57        }
    8.58      end
    8.59    end
    8.60 -}
    8.61 \ No newline at end of file
    8.62 +}
     9.1 --- a/app/main/contact/list.lua	Mon Nov 30 12:00:00 2009 +0100
     9.2 +++ b/app/main/contact/list.lua	Thu Dec 10 12:00:00 2009 +0100
     9.3 @@ -1,5 +1,7 @@
     9.4  slot.put_into("title", _"Contacts")
     9.5  
     9.6 +util.help("contact.list")
     9.7 +
     9.8  execute.view{
     9.9    module = "contact",
    9.10    view = "_list",
    10.1 --- a/app/main/delegation/_action/update.lua	Mon Nov 30 12:00:00 2009 +0100
    10.2 +++ b/app/main/delegation/_action/update.lua	Thu Dec 10 12:00:00 2009 +0100
    10.3 @@ -12,7 +12,7 @@
    10.4  
    10.5  local delegation = Delegation:by_pk(truster_id, area_id, issue_id)
    10.6  
    10.7 -if param.get("delete") then
    10.8 +if param.get("delete") or trustee_id == -1 then
    10.9  
   10.10    if delegation then
   10.11    
    11.1 --- a/app/main/delegation/_show_box.lua	Mon Nov 30 12:00:00 2009 +0100
    11.2 +++ b/app/main/delegation/_show_box.lua	Thu Dec 10 12:00:00 2009 +0100
    11.3 @@ -1,121 +1,192 @@
    11.4 -slot.select("delegation", function()
    11.5 -
    11.6 -  local delegation
    11.7 -  local area_id
    11.8 -  local issue_id
    11.9 -
   11.10 -  local scope = "global"
   11.11 -
   11.12 -  if param.get("initiative_id", atom.integer) then
   11.13 -    issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id
   11.14 -    scope = "issue"
   11.15 -  end
   11.16 -
   11.17 -  if param.get("issue_id", atom.integer) then
   11.18 -    issue_id = param.get("issue_id", atom.integer)
   11.19 -    scope = "issue"
   11.20 -  end
   11.21 -
   11.22 -  if param.get("area_id", atom.integer) then
   11.23 -    area_id = param.get("area_id", atom.integer)
   11.24 -    scope = "area"
   11.25 -  end
   11.26 -
   11.27 -
   11.28 +slot.select("actions", function()
   11.29  
   11.30 -  local delegation
   11.31 -
   11.32 -  if issue_id then
   11.33 -    delegation = Delegation:by_pk(app.session.member.id, nil, issue_id)
   11.34 -    if not delegation then
   11.35 -      local issue = Issue:by_id(issue_id)
   11.36 -      delegation = Delegation:by_pk(app.session.member.id, issue.area_id)
   11.37 -    end
   11.38 -  elseif area_id then
   11.39 -    delegation = Delegation:by_pk(app.session.member.id, area_id)
   11.40 -  end
   11.41 -
   11.42 -  if not delegation then
   11.43 -    delegation = Delegation:by_pk(app.session.member.id)
   11.44 -  end
   11.45 -  if delegation then
   11.46 -    ui.container{
   11.47 -      attr = {
   11.48 -        class = "head",
   11.49 -        style = "cursor: pointer;",
   11.50 -        onclick = "document.getElementById('delegation_content').style.display = 'block';"
   11.51 -      },
   11.52 -      content = _"Your vote is delegated. [more]"
   11.53 -    }
   11.54 -    ui.container{
   11.55 -      attr = { class = "content", id = "delegation_content" },
   11.56 -      content = function()
   11.57 +  ui.container{
   11.58 +    attr = { class = "delegation vote_info"},
   11.59 +    content = function()
   11.60 +    
   11.61 +      local delegation
   11.62 +      local area_id
   11.63 +      local issue_id
   11.64 +    
   11.65 +      local scope = "global"
   11.66 +    
   11.67 +      if param.get("initiative_id", atom.integer) then
   11.68 +        issue_id = Initiative:by_id(param.get("initiative_id", atom.integer)).issue_id
   11.69 +        scope = "issue"
   11.70 +      end
   11.71 +    
   11.72 +      if param.get("issue_id", atom.integer) then
   11.73 +        issue_id = param.get("issue_id", atom.integer)
   11.74 +        scope = "issue"
   11.75 +      end
   11.76 +    
   11.77 +      if param.get("area_id", atom.integer) then
   11.78 +        area_id = param.get("area_id", atom.integer)
   11.79 +        scope = "area"
   11.80 +      end
   11.81 +    
   11.82 +    
   11.83 +    
   11.84 +      local delegation
   11.85 +    
   11.86 +      if issue_id then
   11.87 +        delegation = Delegation:by_pk(app.session.member.id, nil, issue_id)
   11.88 +        if not delegation then
   11.89 +          local issue = Issue:by_id(issue_id)
   11.90 +          delegation = Delegation:by_pk(app.session.member.id, issue.area_id)
   11.91 +        end
   11.92 +      elseif area_id then
   11.93 +        delegation = Delegation:by_pk(app.session.member.id, area_id)
   11.94 +      end
   11.95 +    
   11.96 +      if not delegation then
   11.97 +        delegation = Delegation:by_pk(app.session.member.id)
   11.98 +      end
   11.99 +      if delegation then
  11.100          ui.container{
  11.101            attr = {
  11.102 -            class = "close",
  11.103 +            title = _"Click for details",
  11.104 +            class = "head head_active",
  11.105              style = "cursor: pointer;",
  11.106 -            onclick = "document.getElementById('delegation_content').style.display = 'none';"
  11.107 +            onclick = "document.getElementById('delegation_content').style.display = 'block';"
  11.108            },
  11.109 -          content = _"X"
  11.110 +          content = function()
  11.111 +            ui.image{
  11.112 +              static = "icons/16/error.png"
  11.113 +            }
  11.114 +            if delegation.issue_id then
  11.115 +              slot.put(_"Issue delegation active")
  11.116 +            elseif delegation.area_id then
  11.117 +              slot.put(_"Area wide delegation active")
  11.118 +            else
  11.119 +              slot.put(_"Global delegation active")
  11.120 +            end
  11.121 +            ui.image{
  11.122 +              static = "icons/16/dropdown.png"
  11.123 +            }
  11.124 +          end
  11.125          }
  11.126 -
  11.127 -        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 }
  11.128 -
  11.129 -        for i, record in ipairs(delegation_chain) do
  11.130 -          local style
  11.131 -          execute.view{
  11.132 -            module = "member",
  11.133 -            view = "_show_thumb",
  11.134 -            params = { member = record }
  11.135 -          }
  11.136 -          slot.put("<br style='clear: left'/>")
  11.137 -          if record.scope_out then
  11.138 +        ui.container{
  11.139 +          attr = { class = "content", id = "delegation_content" },
  11.140 +          content = function()
  11.141              ui.container{
  11.142 -              attr = { class = "delegation_info" },
  11.143 +              attr = {
  11.144 +                class = "close",
  11.145 +                style = "cursor: pointer;",
  11.146 +                onclick = "document.getElementById('delegation_content').style.display = 'none';"
  11.147 +              },
  11.148                content = function()
  11.149 -                ui.image{
  11.150 -                  attr = { class = "delegation_arrow" },
  11.151 -                  static = "delegation_arrow_vertical.jpg"
  11.152 -                }
  11.153 +                ui.image{ static = "icons/16/cross.png" }
  11.154 +              end
  11.155 +            }
  11.156 +    
  11.157 +            local delegation_chain = Member:new_selector()
  11.158 +              :add_field("delegation_chain.*")
  11.159 +              :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")
  11.160 +              :add_order_by("index")
  11.161 +              :exec()
  11.162 +    
  11.163 +            for i, record in ipairs(delegation_chain) do
  11.164 +              local style
  11.165 +              local overridden = record.overridden
  11.166 +              if record.scope_in then
  11.167                  ui.container{
  11.168 -                  attr = { class = "delegation_scope" },
  11.169 +                  attr = { class = "delegation_info" },
  11.170                    content = function()
  11.171 -                    if record.scope_out == "global" then
  11.172 -                      slot.put(_"Global delegation")
  11.173 -                    elseif record.scope_out == "area" then
  11.174 -                      slot.put(_"Area delegation")
  11.175 -                    elseif record.scope_out == "issue" then
  11.176 -                      slot.put(_"Issue delegation")
  11.177 +                    if not overridden then
  11.178 +                      ui.image{
  11.179 +                        attr = { class = "delegation_arrow" },
  11.180 +                        static = "delegation_arrow_vertical.jpg"
  11.181 +                      }
  11.182 +                    else
  11.183 +                      ui.image{
  11.184 +                        attr = { class = "delegation_arrow delegation_arrow_overridden" },
  11.185 +                        static = "delegation_arrow_vertical.jpg"
  11.186 +                      }
  11.187 +                    end
  11.188 +                    ui.container{
  11.189 +                      attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") },
  11.190 +                      content = function()
  11.191 +                        if record.scope_in == "global" then
  11.192 +                          slot.put(_"Global delegation")
  11.193 +                        elseif record.scope_in == "area" then
  11.194 +                          slot.put(_"Area delegation")
  11.195 +                        elseif record.scope_in == "issue" then
  11.196 +                          slot.put(_"Issue delegation")
  11.197 +                        end
  11.198 +                      end
  11.199 +                    }
  11.200 +                    if i == 2 then
  11.201 +                      ui.link{
  11.202 +                        attr = { class = "revoke" },
  11.203 +                        content = function()
  11.204 +                          ui.image{ static = "icons/16/delete.png" }
  11.205 +                          slot.put(_"Revoke")
  11.206 +                        end,
  11.207 +                        module = "delegation",
  11.208 +                        action = "update",
  11.209 +                        params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true },
  11.210 +                        routing = {
  11.211 +                          default = {
  11.212 +                            mode = "redirect",
  11.213 +                            module = request.get_module(),
  11.214 +                            view = request.get_view(),
  11.215 +                            id = param.get_id_cgi(),
  11.216 +                            params = param.get_all_cgi()
  11.217 +                          }
  11.218 +                        }
  11.219 +                      }
  11.220                      end
  11.221                    end
  11.222                  }
  11.223 -                if record.id == app.session.member.id then
  11.224 -                  ui.link{
  11.225 -                    attr = { class = "revoke" },
  11.226 -                    content = function()
  11.227 -                      ui.image{ static = "icons/16/delete.png" }
  11.228 -                      slot.put(_"Revoke")
  11.229 -                    end,
  11.230 -                    module = "delegation",
  11.231 -                    action = "update",
  11.232 -                    params = { issue_id = delegation.issue_id, area_id = delegation.area_id, delete = true },
  11.233 -                    routing = {
  11.234 -                      default = {
  11.235 -                        mode = "redirect",
  11.236 -                        module = request.get_module(),
  11.237 -                        view = request.get_view(),
  11.238 -                        id = param.get_id_cgi(),
  11.239 -                        params = param.get_all_cgi()
  11.240 -                      }
  11.241 -                    }
  11.242 +              end
  11.243 +              ui.container{
  11.244 +                attr = { class = overridden and "delegation_overridden" or "" },
  11.245 +                content = function()
  11.246 +                  execute.view{
  11.247 +                    module = "member",
  11.248 +                    view = "_show_thumb",
  11.249 +                    params = { member = record }
  11.250                    }
  11.251                  end
  11.252 +              }
  11.253 +              if record.participation and not record.overridden then
  11.254 +                ui.container{
  11.255 +                  attr = { class = "delegation_participation" },
  11.256 +                  content = function()
  11.257 +                    slot.put("<br /><br />-----> Participation<br />")
  11.258 +                  end
  11.259 +                }
  11.260                end
  11.261 -            }
  11.262 +              slot.put("<br style='clear: left'/>")
  11.263 +            end
  11.264            end
  11.265 -        end
  11.266 +        }
  11.267        end
  11.268 -    }
  11.269 -  end
  11.270 -
  11.271 +      ui.link{
  11.272 +        content = function()
  11.273 +          ui.image{ static = "icons/16/table_go.png" }
  11.274 +          if scope == "global" and delegation then
  11.275 +            slot.put(_"Change global delegation")
  11.276 +          elseif scope == "global" and not delegation then
  11.277 +            slot.put(_"Set global delegation")
  11.278 +          elseif scope == "area" and delegation and delegation.area_id then
  11.279 +            slot.put(_"Change area delegation")
  11.280 +          elseif scope == "area" and not (delegation and delegation.area_id) then
  11.281 +            slot.put(_"Set area delegation")
  11.282 +          elseif scope == "issue" and delegation and delegation.issue_id then
  11.283 +            slot.put(_"Change issue delegation")
  11.284 +          elseif scope == "issue" and not (delegation and delegation.issue_id) then
  11.285 +            slot.put(_"Set issue delegation")
  11.286 +          end
  11.287 +        end,
  11.288 +        module = "delegation",
  11.289 +        view = "new",
  11.290 +        params = {
  11.291 +          area_id = area_id,
  11.292 +          issue_id = issue_id 
  11.293 +        }
  11.294 +      }
  11.295 +    end
  11.296 +  }
  11.297  end)
    12.1 --- a/app/main/delegation/new.lua	Mon Nov 30 12:00:00 2009 +0100
    12.2 +++ b/app/main/delegation/new.lua	Thu Dec 10 12:00:00 2009 +0100
    12.3 @@ -1,18 +1,59 @@
    12.4  local area = Area:by_id(param.get("area_id", atom.integer))
    12.5  if area then
    12.6    slot.put_into("title", encode.html(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name)))
    12.7 +  util.help("delegation.new.area")
    12.8  end
    12.9  
   12.10  local issue = Issue:by_id(param.get("issue_id", atom.integer))
   12.11  if issue then
   12.12    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)))
   12.13 +  util.help("delegation.new.issue")
   12.14  end
   12.15  
   12.16 +if not area and not issue then
   12.17 +  slot.put_into("title", encode.html(_"Set global delegation"))
   12.18 +  util.help("delegation.new.global")
   12.19 +end
   12.20 +
   12.21 +slot.select("actions", function()
   12.22 +  if issue then
   12.23 +    ui.link{
   12.24 +      module = "issue",
   12.25 +      view = "show",
   12.26 +      id = issue.id,
   12.27 +      content = function()
   12.28 +          ui.image{ static = "icons/16/cancel.png" }
   12.29 +          slot.put(_"Cancel")
   12.30 +      end,
   12.31 +    }
   12.32 +  elseif area then
   12.33 +    ui.link{
   12.34 +      module = "area",
   12.35 +      view = "show",
   12.36 +      id = area.id,
   12.37 +      content = function()
   12.38 +          ui.image{ static = "icons/16/cancel.png" }
   12.39 +          slot.put(_"Cancel")
   12.40 +      end,
   12.41 +    }
   12.42 +  else
   12.43 +    ui.link{
   12.44 +      module = "index",
   12.45 +      view = "index",
   12.46 +      content = function()
   12.47 +          ui.image{ static = "icons/16/cancel.png" }
   12.48 +          slot.put(_"Cancel")
   12.49 +      end,
   12.50 +    }
   12.51 +  end
   12.52 +end)
   12.53 +
   12.54 +
   12.55  
   12.56  local contact_members = Member:new_selector()
   12.57    :add_where{ "contact.member_id = ?", app.session.member.id }
   12.58    :join("contact", nil, "member.id = contact.other_member_id")
   12.59 -  :add_order_by("member.login")
   12.60 +  :add_order_by("member.name")
   12.61    :exec()
   12.62  
   12.63  
   12.64 @@ -27,19 +68,29 @@
   12.65    routing = {
   12.66      default = {
   12.67        mode = "redirect",
   12.68 -      module = area and "area" or "issue",
   12.69 -      view = "show",
   12.70 -      id = area and area.id or issue.id,
   12.71 +      module = area and "area" or issue and "issue" or "index",
   12.72 +      view = (area or issue) and "show" or "index",
   12.73 +      id = area and area.id or issue and issue.id or nil,
   12.74      }
   12.75    },
   12.76    content = function()
   12.77 +    records = {
   12.78 +      {
   12.79 +        id = "-1",
   12.80 +        name = _"No delegation"
   12.81 +      }
   12.82 +    }
   12.83 +    for i, record in ipairs(contact_members) do
   12.84 +      records[#records+1] = record
   12.85 +    end
   12.86 +
   12.87      ui.field.select{
   12.88        label = _"Trustee",
   12.89        name = "trustee_id",
   12.90 -      foreign_records = contact_members,
   12.91 +      foreign_records = records,
   12.92        foreign_id = "id",
   12.93 -      foreign_name = "name"
   12.94 +      foreign_name = "name",
   12.95      }
   12.96      ui.submit{ text = _"Save" }
   12.97    end
   12.98 -}
   12.99 \ No newline at end of file
  12.100 +}
    13.1 --- a/app/main/draft/_action/add.lua	Mon Nov 30 12:00:00 2009 +0100
    13.2 +++ b/app/main/draft/_action/add.lua	Thu Dec 10 12:00:00 2009 +0100
    13.3 @@ -4,6 +4,17 @@
    13.4    local draft = Draft:new()
    13.5    draft.author_id = app.session.member.id
    13.6    draft.initiative_id = initiative.id
    13.7 +  local formatting_engine = param.get("formatting_engine")
    13.8 +  local formatting_engine_valid = false
    13.9 +  for fe, dummy in pairs(config.formatting_engine_executeables) do
   13.10 +    if formatting_engine == fe then
   13.11 +      formatting_engine_valid = true
   13.12 +    end
   13.13 +  end
   13.14 +  if not formatting_engine_valid then
   13.15 +    error("invalid formatting engine!")
   13.16 +  end
   13.17 +  draft.formatting_engine = formatting_engine
   13.18    draft.content = param.get("content")
   13.19    draft:save()
   13.20  
    14.1 --- a/app/main/draft/_show.lua	Mon Nov 30 12:00:00 2009 +0100
    14.2 +++ b/app/main/draft/_show.lua	Thu Dec 10 12:00:00 2009 +0100
    14.3 @@ -9,9 +9,9 @@
    14.4      ui.field.text{ label = _"Author", name = "author_name" }
    14.5      ui.field.timestamp{ label = _"Created at", name = "created" }
    14.6      ui.container{
    14.7 -      attr = { class = "draft_content" },
    14.8 +      attr = { class = "draft_content wiki" },
    14.9        content = function()
   14.10 -        slot.put(format.wiki_text(draft.content))
   14.11 +        slot.put(format.wiki_text(draft.content, draft.formatting_engine))
   14.12        end
   14.13      }
   14.14    end
    15.1 --- a/app/main/draft/new.lua	Mon Nov 30 12:00:00 2009 +0100
    15.2 +++ b/app/main/draft/new.lua	Thu Dec 10 12:00:00 2009 +0100
    15.3 @@ -1,7 +1,19 @@
    15.4 -slot.put_into("title", _"Add new draft")
    15.5 +slot.put_into("title", _"Edit draft")
    15.6  
    15.7  local initiative = Initiative:by_id(param.get("initiative_id"))
    15.8  
    15.9 +slot.select("actions", function()
   15.10 +  ui.link{
   15.11 +    content = function()
   15.12 +        ui.image{ static = "icons/16/cancel.png" }
   15.13 +        slot.put(_"Cancel")
   15.14 +    end,
   15.15 +    module = "initiative",
   15.16 +    view = "show",
   15.17 +    id = initiative.id
   15.18 +  }
   15.19 +end)
   15.20 +
   15.21  ui.form{
   15.22    record = initiative.current_draft,
   15.23    attr = { class = "vertical" },
   15.24 @@ -19,6 +31,16 @@
   15.25    content = function()
   15.26  
   15.27      ui.field.text{ label = _"Author", value = app.session.member.name, readonly = true }
   15.28 +    ui.field.select{
   15.29 +      label = _"Wiki engine",
   15.30 +      name = "formatting_engine",
   15.31 +      foreign_records = {
   15.32 +        { id = "rocketwiki", name = "RocketWiki" },
   15.33 +        { id = "compat", name = _"Traditional wiki syntax" }
   15.34 +      },
   15.35 +      foreign_id = "id",
   15.36 +      foreign_name = "name"
   15.37 +    }
   15.38      ui.field.text{
   15.39        label = _"Content",
   15.40        name = "content",
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/app/main/help/_action/update.lua	Thu Dec 10 12:00:00 2009 +0100
    16.3 @@ -0,0 +1,15 @@
    16.4 +local help_ident = param.get("help_ident")
    16.5 +local hide = param.get("hide", atom.boolean)
    16.6 +
    16.7 +local setting_key = "liquidfeedback_frontend_hidden_help_" .. help_ident
    16.8 +local setting = Setting:by_pk(app.session.member.id, setting_key)
    16.9 +
   16.10 +if hide == true and not setting then
   16.11 +  setting = Setting:new()
   16.12 +  setting.member_id = app.session.member.id
   16.13 +  setting.key = setting_key
   16.14 +  setting.value = "hidden"
   16.15 +  setting:save()
   16.16 +elseif hide == false and setting then
   16.17 +  setting:destroy()
   16.18 +end
    17.1 --- a/app/main/index/_action/set_lang.lua	Mon Nov 30 12:00:00 2009 +0100
    17.2 +++ b/app/main/index/_action/set_lang.lua	Thu Dec 10 12:00:00 2009 +0100
    17.3 @@ -1,3 +1,5 @@
    17.4 -app.session.lang = param.get("lang")
    17.5 -
    17.6 -app.session:save()
    17.7 \ No newline at end of file
    17.8 +local lang = param.get("lang")
    17.9 +if lang == "de" or lang == "en" then
   17.10 +  app.session.lang = param.get("lang")
   17.11 +  app.session:save()
   17.12 +end
   17.13 \ No newline at end of file
    18.1 --- a/app/main/index/change_password.lua	Mon Nov 30 12:00:00 2009 +0100
    18.2 +++ b/app/main/index/change_password.lua	Thu Dec 10 12:00:00 2009 +0100
    18.3 @@ -12,6 +12,8 @@
    18.4    }
    18.5  end)
    18.6  
    18.7 +util.help("index.change_password", _"Change password")
    18.8 +
    18.9  ui.form{
   18.10    attr = { class = "vertical" },
   18.11    module = "index",
    19.1 --- a/app/main/index/index.lua	Mon Nov 30 12:00:00 2009 +0100
    19.2 +++ b/app/main/index/index.lua	Thu Dec 10 12:00:00 2009 +0100
    19.3 @@ -1,10 +1,11 @@
    19.4  slot.select("title", function()
    19.5 -  ui.image{
    19.6 -    attr = { class = "avatar" },
    19.7 -    module = "member",
    19.8 -    view = "avatar",
    19.9 -    extension = "jpg",
   19.10 -    id = app.session.member.id
   19.11 +  execute.view{
   19.12 +    module = "member_image",
   19.13 +    view = "_show",
   19.14 +    params = {
   19.15 +      member = app.session.member, 
   19.16 +      image_type = "avatar"
   19.17 +    }
   19.18    }
   19.19  end)
   19.20  
   19.21 @@ -41,27 +42,28 @@
   19.22  slot.put_into("title", encode.html(config.app_title))
   19.23  
   19.24  slot.select("actions", function()
   19.25 -  slot.put(_"Logged in as:")
   19.26 -  slot.put(" <b>")
   19.27 -  slot.put(app.session.member.login)
   19.28 -  slot.put("</b> | ")
   19.29 +
   19.30 +  ui.link{
   19.31 +    content = function()
   19.32 +        ui.image{ static = "icons/16/application_form.png" }
   19.33 +        slot.put(_"Edit my profile")
   19.34 +    end,
   19.35 +    module = "member",
   19.36 +    view = "edit"
   19.37 +  }
   19.38  
   19.39    ui.link{
   19.40      content = function()
   19.41          ui.image{ static = "icons/16/user_gray.png" }
   19.42 -        slot.put(_"Upload avatar")
   19.43 +        slot.put(_"Upload images")
   19.44      end,
   19.45      module = "member",
   19.46 -    view = "edit_avatar"
   19.47 +    view = "edit_images"
   19.48    }
   19.49  
   19.50 -  ui.link{
   19.51 -    content = function()
   19.52 -        ui.image{ static = "icons/16/application_form.png" }
   19.53 -        slot.put(_"Edit my page")
   19.54 -    end,
   19.55 -    module = "member",
   19.56 -    view = "edit"
   19.57 +  execute.view{
   19.58 +    module = "delegation",
   19.59 +    view = "_show_box"
   19.60    }
   19.61  
   19.62    ui.link{
   19.63 @@ -72,8 +74,28 @@
   19.64      module = "index",
   19.65      view = "change_password"
   19.66    }
   19.67 +
   19.68  end)
   19.69  
   19.70 +local lang = locale.get("lang")
   19.71 +local basepath = request.get_app_basepath() 
   19.72 +local file_name = basepath .. "/locale/motd/" .. lang .. ".txt"
   19.73 +local file = io.open(file_name)
   19.74 +if file ~= nil then
   19.75 +  local help_text = file:read("*a")
   19.76 +  if #help_text > 0 then
   19.77 +    ui.container{
   19.78 +      attr = { class = "motd wiki" },
   19.79 +      content = function()
   19.80 +        slot.put(format.wiki_text(help_text))
   19.81 +      end
   19.82 +    }
   19.83 +  end
   19.84 +end
   19.85 +
   19.86 +
   19.87 +util.help("index.index", _"Home")
   19.88 +
   19.89  execute.view{
   19.90    module = "member",
   19.91    view = "_show",
    20.1 --- a/app/main/initiative/_action/create.lua	Mon Nov 30 12:00:00 2009 +0100
    20.2 +++ b/app/main/initiative/_action/create.lua	Thu Dec 10 12:00:00 2009 +0100
    20.3 @@ -29,6 +29,17 @@
    20.4  
    20.5  local draft = Draft:new()
    20.6  draft.initiative_id = initiative.id
    20.7 +local formatting_engine = param.get("formatting_engine")
    20.8 +local formatting_engine_valid = false
    20.9 +for fe, dummy in pairs(config.formatting_engine_executeables) do
   20.10 +  if formatting_engine == fe then
   20.11 +    formatting_engine_valid = true
   20.12 +  end
   20.13 +end
   20.14 +if not formatting_engine_valid then
   20.15 +  error("invalid formatting engine!")
   20.16 +end
   20.17 +draft.formatting_engine = formatting_engine
   20.18  draft.content = param.get("draft")
   20.19  draft.author_id = app.session.member.id
   20.20  draft:save()
    21.1 --- a/app/main/initiative/_list.lua	Mon Nov 30 12:00:00 2009 +0100
    21.2 +++ b/app/main/initiative/_list.lua	Thu Dec 10 12:00:00 2009 +0100
    21.3 @@ -66,7 +66,7 @@
    21.4                  local max_value = record.issue.voter_count
    21.5                  ui.bargraph{
    21.6                    max_value = max_value,
    21.7 -                  width = 200,
    21.8 +                  width = 100,
    21.9                    bars = {
   21.10                      { color = "#0a0", value = record.positive_votes },
   21.11                      { color = "#aaa", value = max_value - record.negative_votes - record.positive_votes },
   21.12 @@ -78,7 +78,7 @@
   21.13                local max_value = (record.issue.population or 0)
   21.14                ui.bargraph{
   21.15                  max_value = max_value,
   21.16 -                width = 200,
   21.17 +                width = 100,
   21.18                  bars = {
   21.19                    { color = "#0a0", value = (record.satisfied_supporter_count or 0) },
   21.20                    { color = "#8f8", value = (record.supporter_count or 0) - (record.satisfied_supporter_count or 0) },
    22.1 --- a/app/main/initiative/edit.lua	Mon Nov 30 12:00:00 2009 +0100
    22.2 +++ b/app/main/initiative/edit.lua	Thu Dec 10 12:00:00 2009 +0100
    22.3 @@ -2,6 +2,18 @@
    22.4  
    22.5  slot.put_into("title", _"Edit initiative")
    22.6  
    22.7 +slot.select("actions", function()
    22.8 +  ui.link{
    22.9 +    content = function()
   22.10 +        ui.image{ static = "icons/16/cancel.png" }
   22.11 +        slot.put(_"Cancel")
   22.12 +    end,
   22.13 +    module = "initiative",
   22.14 +    view = "show",
   22.15 +    id = initiative.id
   22.16 +  }
   22.17 +end)
   22.18 +
   22.19  ui.form{
   22.20    record = initiative,
   22.21    module = "initiative",
    23.1 --- a/app/main/initiative/new.lua	Mon Nov 30 12:00:00 2009 +0100
    23.2 +++ b/app/main/initiative/new.lua	Thu Dec 10 12:00:00 2009 +0100
    23.3 @@ -38,8 +38,18 @@
    23.4          foreign_name = "name"
    23.5        }
    23.6      end
    23.7 -    ui.field.text{ label = _"Name",  name = "name" }
    23.8 -    ui.field.text{ label = _"Discussion URL",  name = "discussion_url" }
    23.9 +    ui.field.text{ label = _"Name", name = "name" }
   23.10 +    ui.field.text{ label = _"Discussion URL", name = "discussion_url" }
   23.11 +    ui.field.select{
   23.12 +      label = _"Wiki engine",
   23.13 +      name = "formatting_engine",
   23.14 +      foreign_records = {
   23.15 +        { id = "rocketwiki", name = "RocketWiki" },
   23.16 +        { id = "compat", name = _"Traditional wiki syntax" }
   23.17 +      },
   23.18 +      foreign_id = "id",
   23.19 +      foreign_name = "name"
   23.20 +    }
   23.21      ui.field.text{ label = _"Draft", name = "draft", multiline = true, attr = { style = "height: 50ex;" } }
   23.22      ui.submit{ text = _"Save" }
   23.23    end
    24.1 --- a/app/main/initiative/show.lua	Mon Nov 30 12:00:00 2009 +0100
    24.2 +++ b/app/main/initiative/show.lua	Thu Dec 10 12:00:00 2009 +0100
    24.3 @@ -1,5 +1,15 @@
    24.4  local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec()
    24.5  
    24.6 +
    24.7 +
    24.8 +execute.view{
    24.9 +  module = "issue",
   24.10 +  view = "_show_head",
   24.11 +  params = { issue = initiative.issue }
   24.12 +}
   24.13 +
   24.14 +local initiator = Initiator:by_pk(initiative.id, app.session.member.id)
   24.15 +
   24.16  --slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(initiative.id) .. '.rss" />')
   24.17  
   24.18  execute.view{
   24.19 @@ -8,6 +18,8 @@
   24.20    params = { initiative = initiative }
   24.21  }
   24.22  
   24.23 +--[[
   24.24 +
   24.25  execute.view{
   24.26    module = "delegation",
   24.27    view = "_show_box",
   24.28 @@ -20,6 +32,7 @@
   24.29    params = { issue = initiative.issue }
   24.30  }
   24.31  
   24.32 +
   24.33  slot.select("path", function()
   24.34    ui.link{
   24.35      content = _"Area '#{name}'":gsub("#{name}", initiative.issue.area.name),
   24.36 @@ -37,29 +50,27 @@
   24.37  end)
   24.38  
   24.39  slot.put_into("title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) ))
   24.40 +--]]
   24.41 +
   24.42 +slot.put_into("sub_title", encode.html(_"Initiative: '#{name}'":gsub("#{name}", initiative.shortened_name) ))
   24.43  
   24.44  slot.select("actions", function()
   24.45  
   24.46 -  local initiator = Initiator:by_pk(initiative.id, app.session.member.id)
   24.47 -
   24.48 -  if initiator then
   24.49 +  if not initiative.issue.fully_frozen and not initiative.issue.closed then
   24.50      ui.link{
   24.51        content = function()
   24.52 -        ui.image{ static = "icons/16/script_add.png" }
   24.53 -        slot.put(_"Edit draft")
   24.54 +        ui.image{ static = "icons/16/script.png" }
   24.55 +        slot.put(_"Show other initiatives")
   24.56        end,
   24.57 -      module = "draft",
   24.58 -      view = "new",
   24.59 -      params = { initiative_id = initiative.id }
   24.60 +      module = "issue",
   24.61 +      view = "show",
   24.62 +      id = initiative.issue.id
   24.63      }
   24.64 -  end
   24.65 -
   24.66 -  if not initiative.issue.fully_frozen and not initiative.issue.closed then
   24.67      ui.link{
   24.68        attr = { class = "action" },
   24.69        content = function()
   24.70          ui.image{ static = "icons/16/script_add.png" }
   24.71 -        slot.put(_"Create alternative initiative" )
   24.72 +        slot.put(_"Create alternative initiative")
   24.73        end,
   24.74        module = "initiative",
   24.75        view = "new",
   24.76 @@ -68,28 +79,50 @@
   24.77    end
   24.78  --  ui.twitter("http://example.com/i" .. tostring(initiative.id) .. " " .. initiative.name)
   24.79  
   24.80 -  if initiative.discussion_url and #initiative.discussion_url > 0 then
   24.81 -    ui.link{
   24.82 -      attr = { 
   24.83 -        target = _"blank",
   24.84 -        title = initiative.discussion_url
   24.85 -      },
   24.86 +end)
   24.87 +
   24.88 +
   24.89 +util.help("initiative.show")
   24.90 +
   24.91 +
   24.92 +ui.container{
   24.93 +  attr = { class = "vertical" },
   24.94 +  content = function()
   24.95 +    ui.container{
   24.96 +      attr = { class = "ui_field_label" },
   24.97 +      content = _"Discussion URL"
   24.98 +    }
   24.99 +    ui.tag{
  24.100 +      tag = "span",
  24.101        content = function()
  24.102 -        ui.image{ static = "icons/16/comments.png" }
  24.103 -        slot.put(_"External discussion")
  24.104 -      end,
  24.105 -      external = initiative.discussion_url
  24.106 +        if initiative.discussion_url and #initiative.discussion_url > 0 then
  24.107 +          ui.link{
  24.108 +            attr = {
  24.109 +              class = "actions",
  24.110 +              target = _"blank",
  24.111 +              title = initiative.discussion_url
  24.112 +            },
  24.113 +            content = function()
  24.114 +              slot.put(encode.html(initiative.discussion_url))
  24.115 +            end,
  24.116 +            external = initiative.discussion_url
  24.117 +          }
  24.118 +        end
  24.119 +        slot.put(" ")
  24.120 +        if initiator then
  24.121 +          ui.link{
  24.122 +            attr = { class = "actions" },
  24.123 +            content = _"(change URL)",
  24.124 +            module = "initiative",
  24.125 +            view = "edit",
  24.126 +            id = initiative.id
  24.127 +          }
  24.128 +        end
  24.129 +      end
  24.130      }
  24.131    end
  24.132 -  if initiator then
  24.133 -    ui.link{
  24.134 -      content = _"(change)",
  24.135 -      module = "initiative",
  24.136 -      view = "edit",
  24.137 -      id = initiative.id
  24.138 -    }
  24.139 -  end
  24.140 -end)
  24.141 +}
  24.142 +
  24.143  
  24.144  
  24.145  ui.container{
  24.146 @@ -122,7 +155,14 @@
  24.147        },
  24.148        attr = { class = "vertical" },
  24.149        content = function()
  24.150 -        ui.field.text{ label = _"Name",        name = "name" }
  24.151 +        local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false
  24.152 +        if not supported then
  24.153 +          ui.field.text{
  24.154 +            attr = { class = "warning" },
  24.155 +            value = _"You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."
  24.156 +          }
  24.157 +        end
  24.158 +        ui.field.text{ label = _"Title (80 chars max)",        name = "name" }
  24.159          ui.field.text{ label = _"Description", name = "description", multiline = true }
  24.160          ui.field.select{ 
  24.161            label = _"Degree", 
  24.162 @@ -183,11 +223,23 @@
  24.163    end
  24.164  end
  24.165  
  24.166 +
  24.167  ui.tabs{
  24.168    {
  24.169      name = "current_draft",
  24.170      label = _"Current draft",
  24.171      content = function()
  24.172 +      if initiator then
  24.173 +        ui.link{
  24.174 +          content = function()
  24.175 +            ui.image{ static = "icons/16/script_add.png" }
  24.176 +            slot.put(_"Edit draft")
  24.177 +          end,
  24.178 +          module = "draft",
  24.179 +          view = "new",
  24.180 +          params = { initiative_id = initiative.id }
  24.181 +        }
  24.182 +      end
  24.183        execute.view{ module = "draft", view = "_show", params = { draft = initiative.current_draft } }
  24.184      end
  24.185    },
  24.186 @@ -195,7 +247,14 @@
  24.187      name = "suggestion",
  24.188      label = _"Suggestions",
  24.189      content = function()
  24.190 -      execute.view{ module = "suggestion", view = "_list", params = { suggestions_selector = initiative:get_reference_selector("suggestions") } }
  24.191 +      execute.view{
  24.192 +        module = "suggestion",
  24.193 +        view = "_list",
  24.194 +        params = {
  24.195 +          initiative = initiative,
  24.196 +          suggestions_selector = initiative:get_reference_selector("suggestions")
  24.197 +        }
  24.198 +      }
  24.199        slot.put("<br />")
  24.200        if not initiative.issue.frozen and not initiative.issue.closed then
  24.201          ui.link{
  24.202 @@ -220,8 +279,8 @@
  24.203            initiative = initiative,
  24.204            members_selector =  initiative:get_reference_selector("supporting_members_snapshot")
  24.205              :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id")
  24.206 -            :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")
  24.207 -            :add_field("direct_population_snapshot.weight")
  24.208 +            :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")
  24.209 +            :add_field("direct_interest_snapshot.weight")
  24.210              :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event")
  24.211          }
  24.212        }
    25.1 --- a/app/main/interest/_show_box.lua	Mon Nov 30 12:00:00 2009 +0100
    25.2 +++ b/app/main/interest/_show_box.lua	Thu Dec 10 12:00:00 2009 +0100
    25.3 @@ -1,73 +1,71 @@
    25.4  
    25.5  local issue = param.get("issue", "table")
    25.6  
    25.7 -
    25.8 -slot.select("interest", function()
    25.9 -  local interest = Interest:by_pk(issue.id, app.session.member.id)
   25.10 +local interest = Interest:by_pk(issue.id, app.session.member.id)
   25.11  
   25.12 -  ui.container{
   25.13 -    attr = { 
   25.14 -      class = "head",
   25.15 -      onclick = "document.getElementById('interest_content').style.display = 'block';"
   25.16 -    },
   25.17 -    content = function()
   25.18 -      if interest then
   25.19 -        ui.field.text{ value = _"You are interested. [more]" }
   25.20 -      else
   25.21 -        ui.field.text{ value = _"You are not interested. [more]" }
   25.22 -      end
   25.23 -    end
   25.24 -  }
   25.25 +if interest then
   25.26 +  slot.select("actions", function()
   25.27  
   25.28    ui.container{
   25.29 -    attr = { class = "content", id = "interest_content" },
   25.30 +    attr = { class = "interest vote_info"},
   25.31      content = function()
   25.32 -      ui.container{
   25.33 -        attr = {
   25.34 -          class = "close",
   25.35 -          style = "cursor: pointer;",
   25.36 -          onclick = "document.getElementById('interest_content').style.display = 'none';"
   25.37 -        },
   25.38 -        content = _"X"
   25.39 -      }
   25.40 -      if interest then
   25.41 -        ui.link{
   25.42 -          content = _"Remove my interest",
   25.43 -          module = "interest",
   25.44 -          action = "update",
   25.45 -          params = { issue_id = issue.id, delete = true },
   25.46 -          routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
   25.47 +        ui.container{
   25.48 +          attr = { 
   25.49 +            class = "head head_active",
   25.50 +            onclick = "document.getElementById('interest_content').style.display = 'block';"
   25.51 +          },
   25.52 +          content = function()
   25.53 +            slot.put(_"Your are interested")
   25.54 +            ui.image{
   25.55 +              static = "icons/16/dropdown.png"
   25.56 +            }
   25.57 +          end
   25.58          }
   25.59 -        slot.put("<br />")
   25.60 -        slot.put("<br />")
   25.61 -        if interest.autoreject then
   25.62 -          ui.field.text{ value = _"Autoreject is on." }
   25.63 -          ui.link{
   25.64 -            content = _"Remove autoreject",
   25.65 -            module = "interest",
   25.66 -            action = "update",
   25.67 -            params = { issue_id = issue.id, autoreject = false },
   25.68 -            routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
   25.69 -          }
   25.70 -        else
   25.71 -          ui.field.text{ value = _"Autoreject is off." }
   25.72 -          ui.link{
   25.73 -            content = _"Set autoreject",
   25.74 -            module = "interest",
   25.75 -            action = "update",
   25.76 -            params = { issue_id = issue.id, autoreject = true },
   25.77 -            routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
   25.78 -          }
   25.79 -        end
   25.80 -      else
   25.81 -        ui.link{
   25.82 -          content = _"Add my interest to this issue",
   25.83 -          module = "interest",
   25.84 -          action = "update",
   25.85 -          params = { issue_id = issue.id },
   25.86 -          routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
   25.87 +    
   25.88 +        ui.container{
   25.89 +          attr = { class = "content", id = "interest_content" },
   25.90 +          content = function()
   25.91 +            ui.container{
   25.92 +              attr = {
   25.93 +                class = "close",
   25.94 +                style = "cursor: pointer;",
   25.95 +                onclick = "document.getElementById('interest_content').style.display = 'none';"
   25.96 +              },
   25.97 +              content = function()
   25.98 +                ui.image{ static = "icons/16/cross.png" }
   25.99 +              end
  25.100 +            }
  25.101 +            ui.link{
  25.102 +              content = _"Remove my interest",
  25.103 +              module = "interest",
  25.104 +              action = "update",
  25.105 +              params = { issue_id = issue.id, delete = true },
  25.106 +              routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
  25.107 +            }
  25.108 +            slot.put("<br />")
  25.109 +            slot.put("<br />")
  25.110 +            if interest.autoreject then
  25.111 +              ui.field.text{ value = _"Autoreject is on." }
  25.112 +              ui.link{
  25.113 +                content = _"Remove autoreject",
  25.114 +                module = "interest",
  25.115 +                action = "update",
  25.116 +                params = { issue_id = issue.id, autoreject = false },
  25.117 +                routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
  25.118 +              }
  25.119 +            else
  25.120 +              ui.field.text{ value = _"Autoreject is off." }
  25.121 +              ui.link{
  25.122 +                content = _"Set autoreject",
  25.123 +                module = "interest",
  25.124 +                action = "update",
  25.125 +                params = { issue_id = issue.id, autoreject = true },
  25.126 +                routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
  25.127 +              }
  25.128 +            end
  25.129 +          end
  25.130          }
  25.131        end
  25.132 -    end
  25.133 -  }
  25.134 -end)
  25.135 +    }
  25.136 +  end)
  25.137 +end
  25.138 \ No newline at end of file
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/app/main/issue/_show_head.lua	Thu Dec 10 12:00:00 2009 +0100
    26.3 @@ -0,0 +1,56 @@
    26.4 +local issue = param.get("issue", "table")
    26.5 +
    26.6 +slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(issue.id) .. '.rss" />')
    26.7 +
    26.8 +slot.select("path", function()
    26.9 +  ui.link{
   26.10 +    content = _"Area '#{name}'":gsub("#{name}", issue.area.name),
   26.11 +    module = "area",
   26.12 +    view = "show",
   26.13 +    id = issue.area.id
   26.14 +  }
   26.15 +end)
   26.16 +
   26.17 +slot.put_into("title", encode.html(_"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name)))
   26.18 +
   26.19 +slot.select("actions", function()
   26.20 +  execute.view{
   26.21 +    module = "interest",
   26.22 +    view = "_show_box",
   26.23 +    params = { issue = issue }
   26.24 +  }
   26.25 +  
   26.26 +  execute.view{
   26.27 +    module = "delegation",
   26.28 +    view = "_show_box",
   26.29 +    params = { issue_id = issue.id }
   26.30 +  }
   26.31 +  
   26.32 +  -- TODO performance
   26.33 +  local interest = Interest:by_pk(issue.id, app.session.member.id)
   26.34 +  if not issue.closed and not issue.fully_frozen then
   26.35 +    if not interest then
   26.36 +      ui.link{
   26.37 +        content = function()
   26.38 +          ui.image{ static = "icons/16/user_add.png" }
   26.39 +          slot.put(_"Add my interest")
   26.40 +        end,
   26.41 +        module = "interest",
   26.42 +        action = "update",
   26.43 +        params = { issue_id = issue.id },
   26.44 +        routing = { default = { mode = "redirect", module = "issue", view = "show", id = issue.id } }
   26.45 +      }
   26.46 +    end
   26.47 +  end
   26.48 +
   26.49 +
   26.50 +end)
   26.51 +
   26.52 +
   26.53 +execute.view{
   26.54 +  module = "issue",
   26.55 +  view = "_show_box",
   26.56 +  params = { issue = issue }
   26.57 +}
   26.58 +
   26.59 +--  ui.twitter("http://example.com/t" .. tostring(issue.id))
    27.1 --- a/app/main/issue/show.lua	Mon Nov 30 12:00:00 2009 +0100
    27.2 +++ b/app/main/issue/show.lua	Thu Dec 10 12:00:00 2009 +0100
    27.3 @@ -1,52 +1,12 @@
    27.4  local issue = Issue:by_id(param.get_id())
    27.5  
    27.6 -slot.put_into("html_head", '<link rel="alternate" type="application/rss+xml" title="RSS" href="../show/' .. tostring(issue.id) .. '.rss" />')
    27.7 -
    27.8 -slot.select("path", function()
    27.9 -  ui.link{
   27.10 -    content = _"Area '#{name}'":gsub("#{name}", issue.area.name),
   27.11 -    module = "area",
   27.12 -    view = "show",
   27.13 -    id = issue.area.id
   27.14 -  }
   27.15 -end)
   27.16 -
   27.17 -slot.put_into("title", encode.html(_"Issue ##{id} (#{policy_name})":gsub("#{id}", issue.id):gsub("#{policy_name}", issue.policy.name)))
   27.18 -
   27.19 -slot.select("actions", function()
   27.20 -  if not issue.closed then
   27.21 -    ui.link{
   27.22 -      content = function()
   27.23 -        ui.image{ static = "icons/16/table_go.png" }
   27.24 -        slot.put(_"Delegate")
   27.25 -      end,
   27.26 -      module = "delegation",
   27.27 -      view = "new",
   27.28 -      params = { issue_id = issue.id }
   27.29 -    }
   27.30 -  end
   27.31 -
   27.32 -  ui.twitter("http://example.com/t" .. tostring(issue.id))
   27.33 -
   27.34 -end)
   27.35 -
   27.36  execute.view{
   27.37 -  module = "interest",
   27.38 -  view = "_show_box",
   27.39 +  module = "issue",
   27.40 +  view = "_show_head",
   27.41    params = { issue = issue }
   27.42  }
   27.43  
   27.44 -execute.view{
   27.45 -  module = "delegation",
   27.46 -  view = "_show_box",
   27.47 -  params = { issue_id = issue.id }
   27.48 -}
   27.49 -
   27.50 -execute.view{
   27.51 -  module = "issue",
   27.52 -  view = "_show_box",
   27.53 -  params = { issue = issue }
   27.54 -}
   27.55 +util.help("issue.show")
   27.56  
   27.57  ui.tabs{
   27.58    {
    28.1 --- a/app/main/member/_action/update_avatar.lua	Mon Nov 30 12:00:00 2009 +0100
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,52 +0,0 @@
    28.4 -local member_id = app.session.member_id
    28.5 -
    28.6 -local member_image = MemberImage:by_pk(member_id, "avatar", false)
    28.7 -local member_image_scaled = MemberImage:by_pk(member_id, "avatar", true)
    28.8 -
    28.9 -if param.get("avatar_delete", atom.boolean) then
   28.10 -  if member_image then
   28.11 -    member_image:destroy()
   28.12 -  end
   28.13 -  if member_image_scaled then
   28.14 -    member_image_scaled:destroy()
   28.15 -  end
   28.16 -  slot.put_into("notice", _"Avatar has been deleted")
   28.17 -  return
   28.18 -end
   28.19 -
   28.20 -local data = param.get("avatar")
   28.21 -
   28.22 -local data_scaled, err, status = os.pfilter(data, "convert", "-", "-thumbnail", "48x48", "jpeg:-")
   28.23 -
   28.24 -if status ~= 0 or data_scaled == nil then
   28.25 - error("error while converting image")
   28.26 -end
   28.27 -
   28.28 -if not member_image then
   28.29 -  member_image = MemberImage:new()
   28.30 -  member_image.member_id = member_id
   28.31 -  member_image.image_type = "avatar"
   28.32 -  member_image.scaled = false
   28.33 -  member_image.data = ""
   28.34 -  member_image:save()
   28.35 -end
   28.36 -
   28.37 -if not member_image_scaled then
   28.38 -  member_image_scaled = MemberImage:new()
   28.39 -  member_image_scaled.member_id = member_id
   28.40 -  member_image_scaled.image_type = "avatar"
   28.41 -  member_image_scaled.scaled = true
   28.42 -  member_image_scaled.content_type = true
   28.43 -  member_image_scaled.data = ""
   28.44 -  member_image_scaled:save()
   28.45 -end
   28.46 -
   28.47 -if data and #data > 0 then
   28.48 -  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 }
   28.49 -end
   28.50 -
   28.51 -if data_scaled and #data_scaled > 0 then
   28.52 -  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 }
   28.53 -end
   28.54 -
   28.55 -slot.put_into("notice", _"Avatar has been updated")
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/app/main/member/_action/update_images.lua	Thu Dec 10 12:00:00 2009 +0100
    29.3 @@ -0,0 +1,73 @@
    29.4 +local member_id = app.session.member_id
    29.5 +
    29.6 +local deleted = 0
    29.7 +local updated = 0
    29.8 +
    29.9 +for i, image_type in ipairs{"avatar", "photo"} do
   29.10 +
   29.11 +  local member_image = MemberImage:by_pk(member_id, image_type, false)
   29.12 +  local member_image_scaled = MemberImage:by_pk(member_id, image_type, true)
   29.13 +
   29.14 +  if param.get(image_type .. "_delete", atom.boolean) then
   29.15 +    if member_image then
   29.16 +      member_image:destroy()
   29.17 +    end
   29.18 +    if member_image_scaled then
   29.19 +      member_image_scaled:destroy()
   29.20 +    end
   29.21 +    deleted = deleted + 1
   29.22 +  else
   29.23 +
   29.24 +    local data = param.get(image_type)
   29.25 +    if data and #data > 0 and #data < 1024*1024 then
   29.26 +      local convert_func = config.member_image_convert_func[image_type]
   29.27 +      local data_scaled, err, status = convert_func(data)
   29.28 +      if status ~= 0 or data_scaled == nil then
   29.29 +      error("error while converting image")
   29.30 +      end
   29.31 +
   29.32 +      if not member_image then
   29.33 +        member_image = MemberImage:new()
   29.34 +        member_image.member_id = member_id
   29.35 +        member_image.image_type = image_type
   29.36 +        member_image.scaled = false
   29.37 +        member_image.data = ""
   29.38 +        member_image:save()
   29.39 +      end
   29.40 +
   29.41 +      if not member_image_scaled then
   29.42 +        member_image_scaled = MemberImage:new()
   29.43 +        member_image_scaled.member_id = member_id
   29.44 +        member_image_scaled.image_type = image_type
   29.45 +        member_image_scaled.scaled = true
   29.46 +        member_image_scaled.content_type = true
   29.47 +        member_image_scaled.data = ""
   29.48 +        member_image_scaled:save()
   29.49 +      end
   29.50 +
   29.51 +      if data and #data > 0 then
   29.52 +        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 }
   29.53 +      end
   29.54 +
   29.55 +      if data_scaled and #data_scaled > 0 then
   29.56 +        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 }
   29.57 +      end
   29.58 +
   29.59 +      updated = updated + 1
   29.60 +    end
   29.61 +  end
   29.62 +end
   29.63 +
   29.64 +if updated > 0 then
   29.65 +  slot.put_into("notice", _("#{number} Image(s) has been updated", { number = updated }))
   29.66 +end
   29.67 +if updated > 0 and deleted > 0 then
   29.68 +  slot.put_into("notice", " &middot; ")
   29.69 +end
   29.70 +if deleted > 0 then
   29.71 +  slot.put_into("notice", _("#{number} Image(s) has been deleted", { number = deleted }))
   29.72 +end
   29.73 +
   29.74 +if updated == 0 and deleted == 0 then
   29.75 +  slot.put_into("warning", _("No changes to your images were made"))
   29.76 +end
   29.77 \ No newline at end of file
    30.1 --- a/app/main/member/_show.lua	Mon Nov 30 12:00:00 2009 +0100
    30.2 +++ b/app/main/member/_show.lua	Thu Dec 10 12:00:00 2009 +0100
    30.3 @@ -1,24 +1,116 @@
    30.4  local member = param.get("member", "table")
    30.5  
    30.6 -ui.form{
    30.7 -  attr = { class = "vertical" },
    30.8 -  record = member,
    30.9 -  readonly = true,
   30.10 -  content = function()
   30.11 -    if member.admin then
   30.12 -      ui.field.boolean{ label = _"Admin?",       name = "admin" }
   30.13 +ui.tabs{
   30.14 +  {
   30.15 +    name = "profile",
   30.16 +    label = _"Profile",
   30.17 +    content = function()
   30.18 +      ui.form{
   30.19 +        attr = { class = "member vertical" },
   30.20 +        record = member,
   30.21 +        readonly = true,
   30.22 +        content = function()
   30.23 +
   30.24 +          ui.container{
   30.25 +            attr = { class = "right" },
   30.26 +            content = function()
   30.27 +
   30.28 +            execute.view{
   30.29 +              module = "member_image",
   30.30 +              view = "_show",
   30.31 +              params = {
   30.32 +                member = member,
   30.33 +                image_type = "photo"
   30.34 +              }
   30.35 +            }
   30.36 +
   30.37 +              ui.container{
   30.38 +                attr = { class = "contact_data" },
   30.39 +                content = function()
   30.40 +                end
   30.41 +              }
   30.42 +
   30.43 +            end
   30.44 +          }
   30.45 +
   30.46 +          if member.admin then
   30.47 +            ui.field.boolean{ label = _"Admin?",       name = "admin" }
   30.48 +          end
   30.49 +          if member.locked then
   30.50 +            ui.field.boolean{ label = _"Locked?",      name = "locked" }
   30.51 +          end
   30.52 +          if member.ident_number then
   30.53 +            ui.field.text{    label = _"Ident number", name = "ident_number" }
   30.54 +          end
   30.55 +          ui.field.text{ label = _"Name", name = "name" }
   30.56 +
   30.57 +          if member.realname and #member.realname > 0 then
   30.58 +            ui.field.text{ label = _"Real name", name = "realname" }
   30.59 +          end
   30.60 +          if member.email and #member.email > 0 then
   30.61 +            ui.field.text{ label = _"email", name = "email" }
   30.62 +          end
   30.63 +          if member.xmpp_address and #member.xmpp_address > 0 then
   30.64 +            ui.field.text{ label = _"xmpp", name = "xmpp_address" }
   30.65 +          end
   30.66 +          if member.website and #member.website > 0 then
   30.67 +            ui.field.text{ label = _"Website", name = "website" }
   30.68 +          end
   30.69 +          if member.phone and #member.phone > 0 then
   30.70 +            ui.field.text{ label = _"Phone", name = "phone" }
   30.71 +          end
   30.72 +          if member.mobile_phone and #member.mobile_phone > 0 then
   30.73 +            ui.field.text{ label = _"Mobile phone", name = "mobile_phone" }
   30.74 +          end
   30.75 +          if member.address and #member.address > 0 then
   30.76 +            ui.container{
   30.77 +              content = function()
   30.78 +                ui.tag{
   30.79 +                  tag = "label",
   30.80 +                  attr = { class = "ui_field_label" },
   30.81 +                  content = _"Address"
   30.82 +                }
   30.83 +                ui.tag{
   30.84 +                  tag = "span",
   30.85 +                  content = function()
   30.86 +                    slot.put(encode.html_newlines(member.address))
   30.87 +                  end
   30.88 +                }
   30.89 +              end
   30.90 +            }
   30.91 +          end
   30.92 +          if member.profession and #member.profession > 0 then
   30.93 +            ui.field.text{ label = _"Profession", name = "profession" }
   30.94 +          end
   30.95 +          if member.birthday and #member.birthday > 0 then
   30.96 +            ui.field.text{ label = _"Birthday", name = "birthday" }
   30.97 +          end
   30.98 +          if member.organizational_unit and #member.organizational_unit > 0 then
   30.99 +            ui.field.text{ label = _"Organizational unit", name = "organizational_unit" }
  30.100 +          end
  30.101 +          if member.internal_posts and #member.internal_posts > 0 then
  30.102 +            ui.field.text{ label = _"Internal posts", name = "internal_posts" }
  30.103 +          end
  30.104 +          if member.external_memberships and #member.external_memberships > 0 then
  30.105 +            ui.field.text{ label = _"Memberships", name = "external_memberships", multiline = true }
  30.106 +          end
  30.107 +          if member.external_posts and #member.external_posts > 0 then
  30.108 +            ui.field.text{ label = _"Posts", name = "external_posts", multiline = true }
  30.109 +          end
  30.110 +          slot.put('<br style="clear: right;" />')
  30.111 +
  30.112 +        end
  30.113 +      }
  30.114 +      if member.statement and #member.statement > 0 then
  30.115 +        ui.container{
  30.116 +          attr = { class = "member_statement wiki" },
  30.117 +          content = function()
  30.118 +            slot.put(format.wiki_text(member.statement))
  30.119 +          end
  30.120 +        }
  30.121 +      end
  30.122      end
  30.123 -    if member.locked then
  30.124 -      ui.field.boolean{ label = _"Locked?",      name = "locked" }
  30.125 -    end
  30.126 -    if member.ident_number then
  30.127 -      ui.field.text{    label = _"Ident number", name = "ident_number" }
  30.128 -    end
  30.129 -    ui.submit{        text  = _"Save" }
  30.130 -  end
  30.131 -}
  30.132 -
  30.133 -ui.tabs{
  30.134 +  },
  30.135    {
  30.136      name = "areas",
  30.137      label = _"Areas",
  30.138 @@ -42,8 +134,8 @@
  30.139      end
  30.140    },
  30.141    {
  30.142 -    name = "initiatives",
  30.143 -    label = _"Initiatives",
  30.144 +    name = "supported_initiatives",
  30.145 +    label = _"Supported initiatives",
  30.146      content = function()
  30.147        execute.view{
  30.148          module = "initiative",
  30.149 @@ -53,6 +145,17 @@
  30.150      end
  30.151    },
  30.152    {
  30.153 +    name = "initiatied_initiatives",
  30.154 +    label = _"Initiated initiatives",
  30.155 +    content = function()
  30.156 +      execute.view{
  30.157 +        module = "initiative",
  30.158 +        view = "_list",
  30.159 +        params = { initiatives_selector = member:get_reference_selector("initiated_initiatives") }
  30.160 +      }
  30.161 +    end
  30.162 +  },
  30.163 +  {
  30.164      name = "incoming_delegations",
  30.165      label = _"Incoming delegations",
  30.166      content = function()
  30.167 @@ -64,7 +167,7 @@
  30.168      end
  30.169    },
  30.170    {
  30.171 -    name = "outgoing_delegations",
  30.172 +    name = "Outgoing delegations",
  30.173      label = _"Outgoing delegations",
  30.174      content = function()
  30.175        execute.view{
    31.1 --- a/app/main/member/_show_thumb.lua	Mon Nov 30 12:00:00 2009 +0100
    31.2 +++ b/app/main/member/_show_thumb.lua	Thu Dec 10 12:00:00 2009 +0100
    31.3 @@ -58,19 +58,21 @@
    31.4          end
    31.5        end
    31.6      }
    31.7 -    
    31.8 +
    31.9      ui.link{
   31.10        attr = { title = _"Show member" },
   31.11        module = "member",
   31.12        view = "show",
   31.13        id = member.id,
   31.14        content = function()
   31.15 -        ui.image{
   31.16 -          attr = { width = 48, height = 48 },
   31.17 -          module    = "member",
   31.18 -          view      = "avatar",
   31.19 -          id        = member.id,
   31.20 -          extension = "jpg"
   31.21 +        execute.view{
   31.22 +          module = "member_image",
   31.23 +          view = "_show",
   31.24 +          params = {
   31.25 +            member = member,
   31.26 +            image_type = "avatar",
   31.27 +            show_dummy = true
   31.28 +          }
   31.29          }
   31.30          ui.container{
   31.31            attr = { class = "member_name" },
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/app/main/member/_show_thumb.lua.orig	Thu Dec 10 12:00:00 2009 +0100
    32.3 @@ -0,0 +1,86 @@
    32.4 +local member = param.get("member", "table")
    32.5 +
    32.6 +local issue = param.get("issue", "table")
    32.7 +local initiative = param.get("initiative", "table")
    32.8 +local trustee = param.get("trustee", "table")
    32.9 +
   32.10 +local name
   32.11 +if member.name_highlighted then
   32.12 +  name = encode.highlight(member.name_highlighted)
   32.13 +else
   32.14 +  name = encode.html(member.name)
   32.15 +end
   32.16 +
   32.17 +ui.container{
   32.18 +  attr = { class = "member_thumb" },
   32.19 +  content = function()
   32.20 +    ui.container{
   32.21 +      attr = { class = "flags" },
   32.22 +      content = function()
   32.23 +        if (issue or initiative) and member.weight > 1 then
   32.24 +          local module
   32.25 +          if issue then
   32.26 +            module = "interest"
   32.27 +          elseif initiative then
   32.28 +            module = "supporter"
   32.29 +          end
   32.30 +          ui.link{
   32.31 +            attr = { title = _"Number of incoming delegations, follow link to see more details" },
   32.32 +            content = _("+ #{weight}", { weight = member.weight - 1 }),
   32.33 +            module = module,
   32.34 +            view = "show_incoming",
   32.35 +            params = { 
   32.36 +              member_id = member.id, 
   32.37 +              initiative_id = initiative and initiative.id or nil,
   32.38 +              issue_id = issue and issue.id or nil
   32.39 +            }
   32.40 +          }
   32.41 +        end
   32.42 +        -- TODO performance
   32.43 +        local contact = Contact:by_pk(app.session.member.id, member.id)
   32.44 +        if contact then
   32.45 +          ui.image{
   32.46 +            attr = { 
   32.47 +              alt   = _"You have saved this member as contact",
   32.48 +              title = _"You have saved this member as contact"
   32.49 +            },
   32.50 +            static = "icons/16/bullet_disk.png"
   32.51 +          }
   32.52 +        end
   32.53 +      end
   32.54 +    }
   32.55 +
   32.56 +    ui.link{
   32.57 +      attr = { title = _"Show member" },
   32.58 +      module = "member",
   32.59 +      view = "show",
   32.60 +      id = member.id,
   32.61 +      content = function()
   32.62 +        execute.view{
   32.63 +          module = "member_image",
   32.64 +          view = "_show",
   32.65 +          params = {
   32.66 +            member = member,
   32.67 +            image_type = "avatar",
   32.68 +            show_dummy = true
   32.69 +          }
   32.70 +        }
   32.71 +      end
   32.72 +    }
   32.73 +
   32.74 +    ui.link{
   32.75 +      attr = { title = _"Show member" },
   32.76 +      module = "member",
   32.77 +      view = "show",
   32.78 +      id = member.id,
   32.79 +      content = function()
   32.80 +        ui.container{
   32.81 +          attr = { class = "member_name" },
   32.82 +          content = function()
   32.83 +            slot.put(name)
   32.84 +          end
   32.85 +        }
   32.86 +      end
   32.87 +    }
   32.88 +  end
   32.89 +}
    33.1 --- a/app/main/member/avatar.lua	Mon Nov 30 12:00:00 2009 +0100
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,15 +0,0 @@
    33.4 -local record = MemberImage:by_pk(param.get_id(), "avatar", true)
    33.5 -
    33.6 -if record == nil then
    33.7 -  print('Location: ' .. encode.url{ static = 'avatar.jpg' } .. '\n\n')
    33.8 -  exit()
    33.9 -end
   33.10 -
   33.11 -print('Content-type: ' .. record.content_type .. '\n')
   33.12 -
   33.13 -if record then
   33.14 -  io.stdout:write(record.data)
   33.15 -else
   33.16 -end
   33.17 -
   33.18 -exit()
    34.1 --- a/app/main/member/edit.lua	Mon Nov 30 12:00:00 2009 +0100
    34.2 +++ b/app/main/member/edit.lua	Thu Dec 10 12:00:00 2009 +0100
    34.3 @@ -1,4 +1,4 @@
    34.4 -slot.put_into("title", _"Edit my page")
    34.5 +slot.put_into("title", _"Edit my profile")
    34.6  
    34.7  slot.select("actions", function()
    34.8    ui.link{
    34.9 @@ -11,6 +11,8 @@
   34.10    }
   34.11  end)
   34.12  
   34.13 +util.help("member.edit", _"Edit my page")
   34.14 +
   34.15  ui.form{
   34.16    record = app.session.member,
   34.17    attr = { class = "vertical" },
    35.1 --- a/app/main/member/edit_avatar.lua	Mon Nov 30 12:00:00 2009 +0100
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,33 +0,0 @@
    35.4 -slot.put_into("title", _"Upload avatar")
    35.5 -
    35.6 -slot.select("actions", function()
    35.7 -  ui.link{
    35.8 -    content = function()
    35.9 -        ui.image{ static = "icons/16/cancel.png" }
   35.10 -        slot.put(_"Cancel")
   35.11 -    end,
   35.12 -    module = "index",
   35.13 -    view = "index"
   35.14 -  }
   35.15 -end)
   35.16 -
   35.17 -ui.form{
   35.18 -  record = app.session.member,
   35.19 -  attr = { 
   35.20 -    class = "vertical",
   35.21 -    enctype = 'multipart/form-data'
   35.22 -  },
   35.23 -  module = "member",
   35.24 -  action = "update_avatar",
   35.25 -  routing = {
   35.26 -    ok = {
   35.27 -      mode = "redirect",
   35.28 -      module = "index",
   35.29 -      view = "index"
   35.30 -    }
   35.31 -  },
   35.32 -  content = function()
   35.33 -    ui.field.image{ field_name = "avatar", label = _"Avatar" }
   35.34 -    ui.submit{ value = _"Save" }
   35.35 -  end
   35.36 -}
   35.37 \ No newline at end of file
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/app/main/member/edit_images.lua	Thu Dec 10 12:00:00 2009 +0100
    36.3 @@ -0,0 +1,52 @@
    36.4 +slot.put_into("title", _"Upload images")
    36.5 +
    36.6 +slot.select("actions", function()
    36.7 +  ui.link{
    36.8 +    content = function()
    36.9 +        ui.image{ static = "icons/16/cancel.png" }
   36.10 +        slot.put(_"Cancel")
   36.11 +    end,
   36.12 +    module = "index",
   36.13 +    view = "index"
   36.14 +  }
   36.15 +end)
   36.16 +
   36.17 +util.help("member.edit_images", _"Images")
   36.18 +
   36.19 +ui.form{
   36.20 +  record = app.session.member,
   36.21 +  attr = { 
   36.22 +    class = "vertical",
   36.23 +    enctype = 'multipart/form-data'
   36.24 +  },
   36.25 +  module = "member",
   36.26 +  action = "update_images",
   36.27 +  routing = {
   36.28 +    ok = {
   36.29 +      mode = "redirect",
   36.30 +      module = "index",
   36.31 +      view = "index"
   36.32 +    }
   36.33 +  },
   36.34 +  content = function()
   36.35 +    execute.view{
   36.36 +      module = "member_image",
   36.37 +      view = "_show",
   36.38 +      params = {
   36.39 +        member = app.session.member, 
   36.40 +        image_type = "avatar"
   36.41 +      }
   36.42 +    }
   36.43 +    ui.field.image{ field_name = "avatar", label = _"Avatar" }
   36.44 +    execute.view{
   36.45 +      module = "member_image",
   36.46 +      view = "_show",
   36.47 +      params = {
   36.48 +        member = app.session.member, 
   36.49 +        image_type = "photo"
   36.50 +      }
   36.51 +    }
   36.52 +    ui.field.image{ field_name = "photo", label = _"Photo" }
   36.53 +    ui.submit{ value = _"Save" }
   36.54 +  end
   36.55 +}
   36.56 \ No newline at end of file
    37.1 --- a/app/main/member/list.lua	Mon Nov 30 12:00:00 2009 +0100
    37.2 +++ b/app/main/member/list.lua	Thu Dec 10 12:00:00 2009 +0100
    37.3 @@ -1,7 +1,9 @@
    37.4  slot.put_into("title", _"Member list")
    37.5  
    37.6 +util.help("member.list")
    37.7 +
    37.8  execute.view{
    37.9    module = "member",
   37.10    view = "_list",
   37.11 -  params = { members_selector = Member:new_selector():add_order_by("login") }
   37.12 +  params = { members_selector = Member:new_selector():add_order_by("name") }
   37.13  }
    38.1 --- a/app/main/member/show.lua	Mon Nov 30 12:00:00 2009 +0100
    38.2 +++ b/app/main/member/show.lua	Thu Dec 10 12:00:00 2009 +0100
    38.3 @@ -1,12 +1,13 @@
    38.4  local member = Member:by_id(param.get_id())
    38.5  
    38.6  slot.select("title", function()
    38.7 -  ui.image{
    38.8 -    attr = { class = "avatar" },
    38.9 -    module = "member",
   38.10 -    view = "avatar",
   38.11 -    extension = "jpg",
   38.12 -    id = member.id
   38.13 +  execute.view{
   38.14 +    module = "member_image",
   38.15 +    view = "_show",
   38.16 +    params = {
   38.17 +      member = member,
   38.18 +      image_type = "avatar"
   38.19 +    }
   38.20    }
   38.21  end)
   38.22  
   38.23 @@ -19,9 +20,15 @@
   38.24    local contact = Contact:by_pk(app.session.member.id, member.id)
   38.25    if contact then
   38.26      slot.select("actions", function()
   38.27 -      ui.field.text{ value = _"You have saved this member as contact." }
   38.28 +      ui.container{
   38.29 +        attr = { class = "interest" },
   38.30 +        content = _"You have saved this member as contact."
   38.31 +      }
   38.32        ui.link{
   38.33 -        text = _"Remove from contacts",
   38.34 +        content = function()
   38.35 +          ui.image{ static = "icons/16/book_delete.png" }
   38.36 +          slot.put(encode.html(_"Remove from contacts"))
   38.37 +        end,
   38.38          module = "contact",
   38.39          action = "remove_member",
   38.40          id = contact.other_member_id,
   38.41 @@ -60,6 +67,7 @@
   38.42    end
   38.43  end
   38.44  
   38.45 +util.help("member.show", _"Member page")
   38.46  
   38.47  execute.view{
   38.48    module = "member",
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/app/main/member_image/_show.lua	Thu Dec 10 12:00:00 2009 +0100
    39.3 @@ -0,0 +1,27 @@
    39.4 +local member = param.get("member", "table")
    39.5 +local image_type = param.get("image_type")
    39.6 +local show_dummy = param.get("show_dummy", atom.boolean)
    39.7 +
    39.8 +local image = member:get_reference_selector("images")
    39.9 +  :add_where{ "image_type = ?", image_type }
   39.10 +  :optional_object_mode()
   39.11 +  :exec()
   39.12 +if image or show_dummy then
   39.13 +  if config.fastpath_url_func then
   39.14 +    ui.image{
   39.15 +      attr = { class = "member_image member_image_" .. image_type },
   39.16 +      external = config.fastpath_url_func(member.id, image_type)
   39.17 +    }
   39.18 +  else
   39.19 +    ui.image{
   39.20 +      attr = { class = "member_image member_image_" .. image_type },
   39.21 +      module = "member_image",
   39.22 +      view = "show",
   39.23 +      extension = "jpg",
   39.24 +      id = member.id,
   39.25 +      params = {
   39.26 +        image_type = image_type
   39.27 +      }
   39.28 +    }
   39.29 +  end
   39.30 +end
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/app/main/member_image/show.lua	Thu Dec 10 12:00:00 2009 +0100
    40.3 @@ -0,0 +1,21 @@
    40.4 +local image_type = param.get("image_type")
    40.5 +local record = MemberImage:by_pk(param.get_id(), image_type, true)
    40.6 +
    40.7 +if record == nil then
    40.8 +  local default_file = config.member_image_default_file[image_type]
    40.9 +  if default_file then
   40.10 +    print('Location: ' .. encode.url{ static = default_file } .. '\n\n')
   40.11 +  else
   40.12 +    print('Location: ' .. encode.url{ static = 'icons/16/lightning.png' } .. '\n\n')
   40.13 +  end
   40.14 +  exit()
   40.15 +end
   40.16 +
   40.17 +print('Content-type: ' .. record.content_type .. '\n')
   40.18 +
   40.19 +if record then
   40.20 +  io.stdout:write(record.data)
   40.21 +else
   40.22 +end
   40.23 +
   40.24 +exit()
    41.1 --- a/app/main/membership/_action/update.lua	Mon Nov 30 12:00:00 2009 +0100
    41.2 +++ b/app/main/membership/_action/update.lua	Thu Dec 10 12:00:00 2009 +0100
    41.3 @@ -25,4 +25,4 @@
    41.4  
    41.5  membership:save()
    41.6  
    41.7 -slot.put_into("notice", _"Membership updated")
    41.8 +--slot.put_into("notice", _"Membership updated")
    42.1 --- a/app/main/membership/_show_box.lua	Mon Nov 30 12:00:00 2009 +0100
    42.2 +++ b/app/main/membership/_show_box.lua	Thu Dec 10 12:00:00 2009 +0100
    42.3 @@ -1,34 +1,40 @@
    42.4  local area = param.get("area", "table")
    42.5  
    42.6 +local membership = Membership:by_pk(area.id, app.session.member.id)
    42.7 +
    42.8  slot.select("interest", function()
    42.9 -  local membership = Membership:by_pk(area.id, app.session.member.id)
   42.10  
   42.11 -  ui.container{
   42.12 -    attr = { 
   42.13 -      class = "head",
   42.14 -      onclick = "document.getElementById('membership_content').style.display = 'block';"
   42.15 -    },
   42.16 -    content = function()
   42.17 -      if membership then
   42.18 -        ui.field.text{ value = _"You are member. [more]" }
   42.19 -      else
   42.20 -        ui.field.text{ value = _"You are not a member. [more]" }
   42.21 +  if membership then
   42.22 +  
   42.23 +    ui.container{
   42.24 +      attr = { 
   42.25 +        class = "head head_active",
   42.26 +        onclick = "document.getElementById('membership_content').style.display = 'block';"
   42.27 +      },
   42.28 +      content = function()
   42.29 +        ui.image{
   42.30 +          static = "icons/16/user_green.png"
   42.31 +        }
   42.32 +        slot.put(_"You are member")
   42.33 +        ui.image{
   42.34 +          static = "icons/16/dropdown.png"
   42.35 +        }
   42.36        end
   42.37 -    end
   42.38 -  }
   42.39 -
   42.40 -  ui.container{
   42.41 -    attr = { class = "content", id = "membership_content" },
   42.42 -    content = function()
   42.43 -      ui.container{
   42.44 -        attr = {
   42.45 -          class = "close",
   42.46 -          style = "cursor: pointer;",
   42.47 -          onclick = "document.getElementById('membership_content').style.display = 'none';"
   42.48 -        },
   42.49 -        content = _"X"
   42.50 -      }
   42.51 -      if membership then
   42.52 +    }
   42.53 +    
   42.54 +    ui.container{
   42.55 +      attr = { class = "content", id = "membership_content" },
   42.56 +      content = function()
   42.57 +        ui.container{
   42.58 +          attr = {
   42.59 +            class = "close",
   42.60 +            style = "cursor: pointer;",
   42.61 +            onclick = "document.getElementById('membership_content').style.display = 'none';"
   42.62 +          },
   42.63 +          content = function()
   42.64 +            ui.image{ static = "icons/16/cross.png" }
   42.65 +          end
   42.66 +        }
   42.67          ui.link{
   42.68            content = _"Remove my membership",
   42.69            module = "membership",
   42.70 @@ -55,15 +61,26 @@
   42.71              routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } }
   42.72            }
   42.73          end
   42.74 -      else
   42.75 -        ui.link{
   42.76 -          content = _"Add my membership to this area",
   42.77 -          module = "membership",
   42.78 -          action = "update",
   42.79 -          params = { area_id = area.id },
   42.80 -          routing = { default = { mode = "redirect", module = "area", view = "show", id = area.id } }
   42.81 +      end
   42.82 +    }
   42.83 +  else
   42.84 +    ui.link{
   42.85 +    content = function()
   42.86 +      ui.image{ static = "icons/16/user_add.png" }
   42.87 +      slot.put(_"Become a member")
   42.88 +    end,
   42.89 +      module = "membership",
   42.90 +      action = "update",
   42.91 +      params = { area_id = area.id },
   42.92 +      routing = {
   42.93 +        default = {
   42.94 +          mode = "redirect",
   42.95 +          module = "area",
   42.96 +          view = "show",
   42.97 +          id = area.id
   42.98          }
   42.99 -      end
  42.100 -    end
  42.101 -  }
  42.102 +      }
  42.103 +    }
  42.104 +  end
  42.105 +
  42.106  end)
    43.1 --- a/app/main/suggestion/_list.lua	Mon Nov 30 12:00:00 2009 +0100
    43.2 +++ b/app/main/suggestion/_list.lua	Thu Dec 10 12:00:00 2009 +0100
    43.3 @@ -1,228 +1,292 @@
    43.4 +
    43.5 +local initiative = param.get("initiative", "table")
    43.6  local suggestions_selector = param.get("suggestions_selector", "table")
    43.7  
    43.8 -ui.paginate{
    43.9 +ui.order{
   43.10 +  name = name,
   43.11    selector = suggestions_selector,
   43.12 +  options = {
   43.13 +    {
   43.14 +      name = "all",
   43.15 +      label = _"all",
   43.16 +      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"
   43.17 +    },
   43.18 +    {
   43.19 +      name = "plus2",
   43.20 +      label = _"must",
   43.21 +      order_by = "plus2_unfulfilled_count + plus2_fulfilled_count DESC, id"
   43.22 +    },
   43.23 +    {
   43.24 +      name = "plus",
   43.25 +      label = _"must/should",
   43.26 +      order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count + plus2_fulfilled_count + plus1_fulfilled_count DESC, id"
   43.27 +    },
   43.28 +    {
   43.29 +      name = "minus",
   43.30 +      label = _"must/should not",
   43.31 +      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + minus2_fulfilled_count + minus1_fulfilled_count DESC, id"
   43.32 +    },
   43.33 +    {
   43.34 +      name = "minus2",
   43.35 +      label = _"must not",
   43.36 +      order_by = "minus2_unfulfilled_count + minus2_fulfilled_count DESC, id"
   43.37 +    },
   43.38 +    {
   43.39 +      name = "unfulfilled",
   43.40 +      label = _"not implemented",
   43.41 +      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count + plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id"
   43.42 +    },
   43.43 +    {
   43.44 +      name = "plus2_unfulfilled",
   43.45 +      label = _"must",
   43.46 +      order_by = "plus2_unfulfilled_count DESC, id"
   43.47 +    },
   43.48 +    {
   43.49 +      name = "plus_unfulfilled",
   43.50 +      label = _"must/should",
   43.51 +      order_by = "plus2_unfulfilled_count + plus1_unfulfilled_count DESC, id"
   43.52 +    },
   43.53 +    {
   43.54 +      name = "minus_unfulfilled",
   43.55 +      label = _"must/should not",
   43.56 +      order_by = "minus2_unfulfilled_count + minus1_unfulfilled_count DESC, id"
   43.57 +    },
   43.58 +    {
   43.59 +      name = "minus2_unfulfilled",
   43.60 +      label = _"must not",
   43.61 +      order_by = "minus2_unfulfilled_count DESC, id"
   43.62 +    },
   43.63 +  },
   43.64    content = function()
   43.65 -    ui.list{
   43.66 -      attr = { style = "table-layout: fixed;" },
   43.67 -      records = suggestions_selector:exec(),
   43.68 -      columns = {
   43.69 -        {
   43.70 -          label = _"Suggestion",
   43.71 -          content = function(record)
   43.72 -            ui.link{
   43.73 -              text = record.name,
   43.74 -              module = "suggestion",
   43.75 -              view = "show",
   43.76 -              id = record.id
   43.77 -            }
   43.78 -          end
   43.79 -        },
   43.80 -        {
   43.81 -          label = _"Collective opinion",
   43.82 -          label_attr = { style = "width: 101px;" },
   43.83 -          content = function(record)
   43.84 -            if record.minus2_unfulfilled_count then
   43.85 -              local max_value = record.initiative.issue.population
   43.86 -              ui.bargraph{
   43.87 -                max_value = max_value,
   43.88 -                width = 100,
   43.89 -                bars = {
   43.90 -                  { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count - record.minus2_fulfilled_count - record.minus1_fulfilled_count },
   43.91 -                  { color = "#f88", value = record.minus1_unfulfilled_count + record.minus1_fulfilled_count },
   43.92 -                  { color = "#a00", value = record.minus2_unfulfilled_count + record.minus2_fulfilled_count },
   43.93 -                  { color = "#0a0", value = record.plus2_unfulfilled_count + record.plus2_fulfilled_count },
   43.94 -                  { color = "#8f8", value = record.plus1_unfulfilled_count + record.plus1_fulfilled_count },
   43.95 -                  { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count - record.plus1_fulfilled_count - record.plus2_fulfilled_count },
   43.96 +    ui.paginate{
   43.97 +      selector = suggestions_selector,
   43.98 +      content = function()
   43.99 +        ui.list{
  43.100 +          attr = { style = "table-layout: fixed;" },
  43.101 +          records = suggestions_selector:exec(),
  43.102 +          columns = {
  43.103 +            {
  43.104 +              label = _"Suggestion",
  43.105 +              content = function(record)
  43.106 +                ui.link{
  43.107 +                  text = record.name,
  43.108 +                  module = "suggestion",
  43.109 +                  view = "show",
  43.110 +                  id = record.id
  43.111                  }
  43.112 -              }
  43.113 -            end
  43.114 -          end
  43.115 -        },
  43.116 -        {
  43.117 -          label = _"My opinion",
  43.118 -          content = function(record)
  43.119 -            local degree
  43.120 -            local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.121 -            if opinion then
  43.122 -              degree = opinion.degree
  43.123 -            end
  43.124 -            ui.link{
  43.125 -              attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
  43.126 -              text = _"must not",
  43.127 -              module = "opinion",
  43.128 -              action = "update",
  43.129 -              routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.130 -              params = {
  43.131 -                suggestion_id = record.id,
  43.132 -                degree = -2
  43.133 -              }
  43.134 -            }
  43.135 -            ui.link{
  43.136 -              attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
  43.137 -              text = _"should not",
  43.138 -              module = "opinion",
  43.139 -              action = "update",
  43.140 -              routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.141 -              params = {
  43.142 -                suggestion_id = record.id,
  43.143 -                degree = -1
  43.144 -              }
  43.145 -            }
  43.146 -            ui.link{
  43.147 -              attr = { class = "action" .. (degree == nil and " active" or "") },
  43.148 -              text = _"neutral",
  43.149 -              module = "opinion",
  43.150 -              action = "update",
  43.151 -              routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.152 -              params = {
  43.153 -                suggestion_id = record.id,
  43.154 -                delete = true
  43.155 -              }
  43.156 -            }
  43.157 -            ui.link{
  43.158 -              attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
  43.159 -              text = _"should",
  43.160 -              module = "opinion",
  43.161 -              action = "update",
  43.162 -              routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.163 -              params = {
  43.164 -                suggestion_id = record.id,
  43.165 -                degree = 1
  43.166 -              }
  43.167 -            }
  43.168 -            ui.link{
  43.169 -              attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
  43.170 -              text = _"must",
  43.171 -              module = "opinion",
  43.172 -              action = "update",
  43.173 -              routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.174 -              params = {
  43.175 -                suggestion_id = record.id,
  43.176 -                degree = 2
  43.177 -              }
  43.178 -            }
  43.179 -          end
  43.180 -        },
  43.181 -        {
  43.182 -          content = function(record)
  43.183 -            local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.184 -            if opinion and not opinion.fulfilled then
  43.185 -              ui.image{ static = "icons/16/cross.png" }
  43.186 -            end
  43.187 -          end
  43.188 -        },
  43.189 -        {
  43.190 -          label = _"Suggestion currently not implemented",
  43.191 -          label_attr = { style = "width: 101px;" },
  43.192 -          content = function(record)
  43.193 -            if record.minus2_unfulfilled_count then
  43.194 -              local max_value = record.initiative.issue.population
  43.195 -              ui.bargraph{
  43.196 -                max_value = max_value,
  43.197 -                width = 100,
  43.198 -                bars = {
  43.199 -                  { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count },
  43.200 -                  { color = "#f88", value = record.minus1_unfulfilled_count },
  43.201 -                  { color = "#a00", value = record.minus2_unfulfilled_count },
  43.202 -                  { color = "#0a0", value = record.plus2_unfulfilled_count },
  43.203 -                  { color = "#8f8", value = record.plus1_unfulfilled_count },
  43.204 -                  { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count },
  43.205 -                }
  43.206 -              }
  43.207 -            end
  43.208 -          end
  43.209 -        },
  43.210 -        {
  43.211 -          content = function(record)
  43.212 -            local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.213 -            if opinion and opinion.fulfilled then
  43.214 -                ui.image{ static = "icons/16/tick.png" }
  43.215 -            end
  43.216 -          end
  43.217 -        },
  43.218 -        {
  43.219 -          label = _"Suggestion currently implemented",
  43.220 -          label_attr = { style = "width: 101px;" },
  43.221 -          content = function(record)
  43.222 -            if record.minus2_fulfilled_count then
  43.223 -              local max_value = record.initiative.issue.population
  43.224 -              ui.bargraph{
  43.225 -                max_value = max_value,
  43.226 -                width = 100,
  43.227 -                bars = {
  43.228 -                  { color = "#ddd", value = max_value - record.minus2_fulfilled_count - record.minus1_fulfilled_count },
  43.229 -                  { color = "#f88", value = record.minus1_fulfilled_count },
  43.230 -                  { color = "#a00", value = record.minus2_fulfilled_count },
  43.231 -                  { color = "#0a0", value = record.plus2_fulfilled_count },
  43.232 -                  { color = "#8f8", value = record.plus1_fulfilled_count },
  43.233 -                  { color = "#ddd", value = max_value - record.plus1_fulfilled_count - record.plus2_fulfilled_count },
  43.234 -                }
  43.235 -              }
  43.236 -            end
  43.237 -          end
  43.238 -        },
  43.239 -        {
  43.240 -          label_attr = { style = "width: 200px;" },
  43.241 -          content = function(record)
  43.242 -            local degree
  43.243 -            local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.244 -            if opinion then
  43.245 -              degree = opinion.degree
  43.246 -            end
  43.247 -            if opinion then
  43.248 -              if not opinion.fulfilled then
  43.249 -                local text = ""
  43.250 -                if opinion.degree > 0 then
  43.251 -                  text = _"Mark suggestion as implemented and express satisfaction"
  43.252 -                else
  43.253 -                  text = _"Mark suggestion as implemented and express dissatisfaction"
  43.254 +              end
  43.255 +            },
  43.256 +            {
  43.257 +              label = _"Collective opinion",
  43.258 +              label_attr = { style = "width: 101px;" },
  43.259 +              content = function(record)
  43.260 +                if record.minus2_unfulfilled_count then
  43.261 +                  local max_value = record.initiative.issue.population
  43.262 +                  ui.bargraph{
  43.263 +                    max_value = max_value,
  43.264 +                    width = 50,
  43.265 +                    bars = {
  43.266 +                      { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count - record.minus2_fulfilled_count - record.minus1_fulfilled_count },
  43.267 +                      { color = "#f88", value = record.minus1_unfulfilled_count + record.minus1_fulfilled_count },
  43.268 +                      { color = "#a00", value = record.minus2_unfulfilled_count + record.minus2_fulfilled_count },
  43.269 +                      { color = "#0a0", value = record.plus2_unfulfilled_count + record.plus2_fulfilled_count },
  43.270 +                      { color = "#8f8", value = record.plus1_unfulfilled_count + record.plus1_fulfilled_count },
  43.271 +                      { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count - record.plus1_fulfilled_count - record.plus2_fulfilled_count },
  43.272 +                    }
  43.273 +                  }
  43.274 +                end
  43.275 +              end
  43.276 +            },
  43.277 +            {
  43.278 +              label = _"My opinion",
  43.279 +              content = function(record)
  43.280 +                local degree
  43.281 +                local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.282 +                if opinion then
  43.283 +                  degree = opinion.degree
  43.284                  end
  43.285                  ui.link{
  43.286 -                  attr = { class = "action" },
  43.287 -                  text = text,
  43.288 +                  attr = { class = "action" .. (degree == -2 and " active_red2" or "") },
  43.289 +                  text = _"must not",
  43.290 +                  module = "opinion",
  43.291 +                  action = "update",
  43.292 +                  routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.293 +                  params = {
  43.294 +                    suggestion_id = record.id,
  43.295 +                    degree = -2
  43.296 +                  }
  43.297 +                }
  43.298 +                ui.link{
  43.299 +                  attr = { class = "action" .. (degree == -1 and " active_red1" or "") },
  43.300 +                  text = _"should not",
  43.301 +                  module = "opinion",
  43.302 +                  action = "update",
  43.303 +                  routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.304 +                  params = {
  43.305 +                    suggestion_id = record.id,
  43.306 +                    degree = -1
  43.307 +                  }
  43.308 +                }
  43.309 +                ui.link{
  43.310 +                  attr = { class = "action" .. (degree == nil and " active" or "") },
  43.311 +                  text = _"neutral",
  43.312                    module = "opinion",
  43.313                    action = "update",
  43.314                    routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.315                    params = {
  43.316                      suggestion_id = record.id,
  43.317 -                    fulfilled = true
  43.318 +                    delete = true
  43.319                    }
  43.320                  }
  43.321 -              else
  43.322 -                if opinion.degree > 0 then
  43.323 -                  text = _"Mark suggestion as not implemented and express dissatisfaction"
  43.324 -                else
  43.325 -                  text = _"Mark suggestion as not implemented and express satisfaction"
  43.326 -                end
  43.327                  ui.link{
  43.328 -                  attr = { class = "action" },
  43.329 -                  text = text,
  43.330 +                  attr = { class = "action" .. (degree == 1 and " active_green1" or "") },
  43.331 +                  text = _"should",
  43.332 +                  module = "opinion",
  43.333 +                  action = "update",
  43.334 +                  routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.335 +                  params = {
  43.336 +                    suggestion_id = record.id,
  43.337 +                    degree = 1
  43.338 +                  }
  43.339 +                }
  43.340 +                ui.link{
  43.341 +                  attr = { class = "action" .. (degree == 2 and " active_green2" or "") },
  43.342 +                  text = _"must",
  43.343                    module = "opinion",
  43.344                    action = "update",
  43.345                    routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.346                    params = {
  43.347                      suggestion_id = record.id,
  43.348 -                    fulfilled = false
  43.349 +                    degree = 2
  43.350                    }
  43.351                  }
  43.352                end
  43.353 -            end
  43.354 -          end
  43.355 -        },
  43.356 -        {
  43.357 -          content = function(record)
  43.358 -            local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.359 -            if opinion then
  43.360 -              if (opinion.fulfilled and opinion.degree > 0) or (not opinion.fulfilled and opinion.degree < 0) then
  43.361 -                ui.image{ static = "icons/16/thumb_up_green.png" }
  43.362 -              else
  43.363 -                ui.image{ static = "icons/16/thumb_down_red.png" }
  43.364 +            },
  43.365 +            {
  43.366 +              content = function(record)
  43.367 +                local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.368 +                if opinion and not opinion.fulfilled then
  43.369 +                  ui.image{ static = "icons/16/cross.png" }
  43.370 +                end
  43.371 +              end
  43.372 +            },
  43.373 +            {
  43.374 +              label = _"Suggestion currently not implemented",
  43.375 +              label_attr = { style = "width: 101px;" },
  43.376 +              content = function(record)
  43.377 +                if record.minus2_unfulfilled_count then
  43.378 +                  local max_value = record.initiative.issue.population
  43.379 +                  ui.bargraph{
  43.380 +                    max_value = max_value,
  43.381 +                    width = 50,
  43.382 +                    bars = {
  43.383 +                      { color = "#ddd", value = max_value - record.minus2_unfulfilled_count - record.minus1_unfulfilled_count },
  43.384 +                      { color = "#f88", value = record.minus1_unfulfilled_count },
  43.385 +                      { color = "#a00", value = record.minus2_unfulfilled_count },
  43.386 +                      { color = "#0a0", value = record.plus2_unfulfilled_count },
  43.387 +                      { color = "#8f8", value = record.plus1_unfulfilled_count },
  43.388 +                      { color = "#ddd", value = max_value - record.plus1_unfulfilled_count - record.plus2_unfulfilled_count },
  43.389 +                    }
  43.390 +                  }
  43.391 +                end
  43.392 +              end
  43.393 +            },
  43.394 +            {
  43.395 +              content = function(record)
  43.396 +                local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.397 +                if opinion and opinion.fulfilled then
  43.398 +                    ui.image{ static = "icons/16/tick.png" }
  43.399 +                end
  43.400 +              end
  43.401 +            },
  43.402 +            {
  43.403 +              label = _"Suggestion currently implemented",
  43.404 +              label_attr = { style = "width: 101px;" },
  43.405 +              content = function(record)
  43.406 +                if record.minus2_fulfilled_count then
  43.407 +                  local max_value = record.initiative.issue.population
  43.408 +                  ui.bargraph{
  43.409 +                    max_value = max_value,
  43.410 +                    width = 50,
  43.411 +                    bars = {
  43.412 +                      { color = "#ddd", value = max_value - record.minus2_fulfilled_count - record.minus1_fulfilled_count },
  43.413 +                      { color = "#f88", value = record.minus1_fulfilled_count },
  43.414 +                      { color = "#a00", value = record.minus2_fulfilled_count },
  43.415 +                      { color = "#0a0", value = record.plus2_fulfilled_count },
  43.416 +                      { color = "#8f8", value = record.plus1_fulfilled_count },
  43.417 +                      { color = "#ddd", value = max_value - record.plus1_fulfilled_count - record.plus2_fulfilled_count },
  43.418 +                    }
  43.419 +                  }
  43.420 +                end
  43.421                end
  43.422 -            end
  43.423 -          end
  43.424 -        },
  43.425 -      }
  43.426 +            },
  43.427 +            {
  43.428 +              label_attr = { style = "width: 200px;" },
  43.429 +              content = function(record)
  43.430 +                local degree
  43.431 +                local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.432 +                if opinion then
  43.433 +                  degree = opinion.degree
  43.434 +                end
  43.435 +                if opinion then
  43.436 +                  if not opinion.fulfilled then
  43.437 +                    local text = ""
  43.438 +                    if opinion.degree > 0 then
  43.439 +                      text = _"Mark suggestion as implemented and express satisfaction"
  43.440 +                    else
  43.441 +                      text = _"Mark suggestion as implemented and express dissatisfaction"
  43.442 +                    end
  43.443 +                    ui.link{
  43.444 +                      attr = { class = "action" },
  43.445 +                      text = text,
  43.446 +                      module = "opinion",
  43.447 +                      action = "update",
  43.448 +                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.449 +                      params = {
  43.450 +                        suggestion_id = record.id,
  43.451 +                        fulfilled = true
  43.452 +                      }
  43.453 +                    }
  43.454 +                  else
  43.455 +                    if opinion.degree > 0 then
  43.456 +                      text = _"Mark suggestion as not implemented and express dissatisfaction"
  43.457 +                    else
  43.458 +                      text = _"Mark suggestion as not implemented and express satisfaction"
  43.459 +                    end
  43.460 +                    ui.link{
  43.461 +                      attr = { class = "action" },
  43.462 +                      text = text,
  43.463 +                      module = "opinion",
  43.464 +                      action = "update",
  43.465 +                      routing = { default = { mode = "redirect", module = request.get_module(), view = request.get_view(), id = param.get_id_cgi(), params = param.get_all_cgi() } },
  43.466 +                      params = {
  43.467 +                        suggestion_id = record.id,
  43.468 +                        fulfilled = false
  43.469 +                      }
  43.470 +                    }
  43.471 +                  end
  43.472 +                end
  43.473 +              end
  43.474 +            },
  43.475 +            {
  43.476 +              content = function(record)
  43.477 +                local opinion = Opinion:by_pk(app.session.member.id, record.id)
  43.478 +                if opinion then
  43.479 +                  if (opinion.fulfilled and opinion.degree > 0) or (not opinion.fulfilled and opinion.degree < 0) then
  43.480 +                    ui.image{ static = "icons/16/thumb_up_green.png" }
  43.481 +                  else
  43.482 +                    ui.image{ static = "icons/16/thumb_down_red.png" }
  43.483 +                  end
  43.484 +                end
  43.485 +              end
  43.486 +            },
  43.487 +          }
  43.488 +        }
  43.489 +      end
  43.490      }
  43.491    end
  43.492  }
  43.493 +
  43.494 +if initiative then
  43.495 +  ui.field.timestamp{ label = _"Last snapshot:", value = initiative.issue.snapshot }
  43.496 +end
    44.1 --- a/app/main/suggestion/show.lua	Mon Nov 30 12:00:00 2009 +0100
    44.2 +++ b/app/main/suggestion/show.lua	Thu Dec 10 12:00:00 2009 +0100
    44.3 @@ -23,10 +23,9 @@
    44.4    view = "_list",
    44.5    params = { 
    44.6      opinions_selector = Opinion:new_selector()
    44.7 -      :add_field("member.login", "member_login")
    44.8        :add_field("member.name", "member_name")
    44.9        :add_where{ "suggestion_id = ?", suggestion.id }
   44.10        :join("member", nil, "member.id = opinion.member_id")
   44.11        :add_order_by("member.id DESC")
   44.12    }
   44.13 -}
   44.14 \ No newline at end of file
   44.15 +}
    45.1 --- a/app/main/supporter/_show_box.lua	Mon Nov 30 12:00:00 2009 +0100
    45.2 +++ b/app/main/supporter/_show_box.lua	Thu Dec 10 12:00:00 2009 +0100
    45.3 @@ -1,49 +1,64 @@
    45.4 -    
    45.5  
    45.6  slot.select("support", function()
    45.7 -
    45.8    local initiative = param.get("initiative", "table")
    45.9 -
   45.10 -  if not initiative.issue.frozen and not initiative.issue.closed then
   45.11 -
   45.12 -    local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false
   45.13 -
   45.14 -    local text
   45.15 -    if supported then
   45.16 -      text = _"Direct supporter [change]"
   45.17 -    else
   45.18 -      text = _"No supporter [change]"
   45.19 -    end
   45.20 -    ui.container{
   45.21 -      attr = {
   45.22 -        class = "head",
   45.23 -        style = "cursor: pointer;",
   45.24 -        onclick = "document.getElementById('support_content').style.display = 'block';"
   45.25 -      },
   45.26 -      content = text
   45.27 -    }
   45.28 +  local supported = Supporter:by_pk(initiative.id, app.session.member.id) and true or false
   45.29  
   45.30 -
   45.31 -    ui.container{
   45.32 -      attr = { class = "content", id = "support_content" },
   45.33 -      content = function()
   45.34 -        ui.container{
   45.35 -          attr = {
   45.36 -            class = "close",
   45.37 -            style = "cursor: pointer;",
   45.38 -            onclick = "document.getElementById('support_content').style.display = 'none';"
   45.39 -          },
   45.40 -          content = _"X"
   45.41 -        }
   45.42 +  ui.container{
   45.43 +    attr = { class = "actions" },
   45.44 +    content = function()
   45.45 +      if not initiative.issue.frozen and not initiative.issue.closed then
   45.46          if supported then
   45.47 -          ui.link{
   45.48 +          ui.container{
   45.49 +            attr = {
   45.50 +              class = "head head_active",
   45.51 +              style = "cursor: pointer;",
   45.52 +              onclick = "document.getElementById('support_content').style.display = 'block';"
   45.53 +            },
   45.54 +            content = function()
   45.55 +              ui.image{
   45.56 +                static = "icons/16/thumb_up_green.png"
   45.57 +              }
   45.58 +              slot.put(_"Your are supporter")
   45.59 +              ui.image{
   45.60 +                static = "icons/16/dropdown.png"
   45.61 +              }
   45.62 +            end
   45.63 +          }
   45.64 +          ui.container{
   45.65 +            attr = { class = "content", id = "support_content" },
   45.66              content = function()
   45.67 -              ui.image{ static = "icons/16/thumb_down_red.png" }
   45.68 -              slot.put(_"Remove my support from this initiative")
   45.69 -            end,
   45.70 -            module = "initiative",
   45.71 -            action = "remove_support",
   45.72 -            id = initiative.id
   45.73 +              ui.container{
   45.74 +                attr = {
   45.75 +                  class = "close",
   45.76 +                  style = "cursor: pointer;",
   45.77 +                  onclick = "document.getElementById('support_content').style.display = 'none';"
   45.78 +                },
   45.79 +                content = function()
   45.80 +                  ui.image{ static = "icons/16/cross.png" }
   45.81 +                end
   45.82 +              }
   45.83 +              if supported then
   45.84 +                ui.link{
   45.85 +                  content = function()
   45.86 +                    ui.image{ static = "icons/16/thumb_down_red.png" }
   45.87 +                    slot.put(_"Remove my support from this initiative")
   45.88 +                  end,
   45.89 +                  module = "initiative",
   45.90 +                  action = "remove_support",
   45.91 +                  id = initiative.id,
   45.92 +                  routing = {
   45.93 +                    default = {
   45.94 +                      mode = "redirect",
   45.95 +                      module = request.get_module(),
   45.96 +                      view = request.get_view(),
   45.97 +                      id = param.get_id_cgi(),
   45.98 +                      params = param.get_all_cgi()
   45.99 +                    }
  45.100 +                  }
  45.101 +                }
  45.102 +              else
  45.103 +              end
  45.104 +            end
  45.105            }
  45.106          else
  45.107            ui.link{
  45.108 @@ -53,11 +68,19 @@
  45.109              end,
  45.110              module = "initiative",
  45.111              action = "add_support",
  45.112 -            id = initiative.id
  45.113 +            id = initiative.id,
  45.114 +            routing = {
  45.115 +              default = {
  45.116 +                mode = "redirect",
  45.117 +                module = request.get_module(),
  45.118 +                view = request.get_view(),
  45.119 +                id = param.get_id_cgi(),
  45.120 +                params = param.get_all_cgi()
  45.121 +              }
  45.122 +            }
  45.123            }
  45.124          end
  45.125        end
  45.126 -    }
  45.127 -  end
  45.128 -
  45.129 +    end
  45.130 +  }
  45.131  end)
    46.1 --- a/app/main/supporter/show_incoming.lua	Mon Nov 30 12:00:00 2009 +0100
    46.2 +++ b/app/main/supporter/show_incoming.lua	Thu Dec 10 12:00:00 2009 +0100
    46.3 @@ -3,11 +3,11 @@
    46.4  local member = Member:by_id(param.get("member_id", atom.integer))
    46.5  
    46.6  local members_selector = Member:new_selector()
    46.7 -  :join("delegating_population_snapshot", nil, "delegating_population_snapshot.member_id = member.id")
    46.8 -  :add_where{ "delegating_population_snapshot.issue_id = ?", issue.id }
    46.9 -  :add_where{ "delegating_population_snapshot.event = ?", issue.latest_snapshot_event }
   46.10 -  :add_where{ "delegating_population_snapshot.delegate_member_ids[1] = ?", member.id }
   46.11 -  :add_field{ "delegating_population_snapshot.weight" }
   46.12 +  :join("delegating_interest_snapshot", nil, "delegating_interest_snapshot.member_id = member.id")
   46.13 +  :add_where{ "delegating_interest_snapshot.issue_id = ?", issue.id }
   46.14 +  :add_where{ "delegating_interest_snapshot.event = ?", issue.latest_snapshot_event }
   46.15 +  :add_where{ "delegating_interest_snapshot.delegate_member_ids[1] = ?", member.id }
   46.16 +  :add_field{ "delegating_interest_snapshot.weight" }
   46.17  
   46.18  execute.view{
   46.19    module = "member",
    47.1 --- a/config/default.lua	Mon Nov 30 12:00:00 2009 +0100
    47.2 +++ b/config/default.lua	Thu Dec 10 12:00:00 2009 +0100
    47.3 @@ -1,14 +1,25 @@
    47.4  config.app_name = "LiquidFeedback"
    47.5 -config.app_version = "alpha4"
    47.6 +config.app_version = "alpha5"
    47.7  
    47.8  config.app_title = config.app_name .. " (" .. request.get_config_name() .. " environment)"
    47.9  
   47.10 +config.app_logo = nil
   47.11 +
   47.12  config.app_service_provider = "Snake Oil<br/>10000 Berlin<br/>Germany"
   47.13  
   47.14 -config.member_image_convert = {
   47.15 -  avatar = { "convert", "-", "-thumbnail", "48x48", "jpeg:-" }
   47.16 +config.member_image_convert_func = {
   47.17 +  avatar = function(data) return os.pfilter(data, "convert", "jpeg:-", "-thumbnail",   "48x48", "jpeg:-") end,
   47.18 +  photo =  function(data) return os.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end
   47.19  }
   47.20  
   47.21 +config.member_image_default_file = {
   47.22 +  avatar = "avatar.jpg",
   47.23 +  photo = nil
   47.24 +}
   47.25 +
   47.26 +config.fastpath_url_func = nil
   47.27 +
   47.28 +
   47.29  -- uncomment the following two lines to use C implementations of chosen
   47.30  -- functions and to disable garbage collection during the request, to
   47.31  -- increase speed:
    48.1 --- a/config/development.lua	Mon Nov 30 12:00:00 2009 +0100
    48.2 +++ b/config/development.lua	Thu Dec 10 12:00:00 2009 +0100
    48.3 @@ -1,3 +1,6 @@
    48.4  execute.config("default")
    48.5  
    48.6 -config.wiki_parser_executeable = "/opt/rocketwiki/rocketwiki"
    48.7 +config.formatting_engine_executeables = {
    48.8 +  rocketwiki= "/opt/rocketwiki/rocketwiki-lqfb",
    48.9 +  compat = "/opt/rocketwiki/rocketwiki-lqfb-compat"
   48.10 +}
    49.1 --- a/config/testing.lua	Mon Nov 30 12:00:00 2009 +0100
    49.2 +++ b/config/testing.lua	Thu Dec 10 12:00:00 2009 +0100
    49.3 @@ -1,3 +1,10 @@
    49.4  execute.config("default")
    49.5  
    49.6 -config.wiki_parser_executeable = "/opt/liquid_feedback_testing/rocketwiki/rocketwiki"
    49.7 +config.formatting_engine_executeables = {
    49.8 +  rocketwiki= "/opt/liquid_feedback_testing/rocketwiki/rocketwiki-lqfb",
    49.9 +  compat = "/opt/liquid_feedback_testing/rocketwiki/rocketwiki-lqfb-compat"
   49.10 +}
   49.11 +
   49.12 +config.fastpath_url_func = function(member_id, image_type)
   49.13 +  return "http://www.public-software-group.org/liquid_feedback_testing/fastpath/getpic?" .. tostring(member_id) .. "+" .. tostring(image_type)
   49.14 +end
   49.15 \ No newline at end of file
    50.1 --- a/env/format/wiki_text.lua	Mon Nov 30 12:00:00 2009 +0100
    50.2 +++ b/env/format/wiki_text.lua	Thu Dec 10 12:00:00 2009 +0100
    50.3 @@ -1,6 +1,7 @@
    50.4 -function format.wiki_text(wiki_text)
    50.5 +function format.wiki_text(wiki_text, formatting_engine)
    50.6 +  local formatting_engine = formatting_engine or "rocketwiki"
    50.7    local html, errmsg, exitcode = assert(
    50.8 -    os.pfilter(wiki_text, config.wiki_parser_executeable)
    50.9 +    os.pfilter(wiki_text, config.formatting_engine_executeables[formatting_engine])
   50.10    )
   50.11    if exitcode > 0 then
   50.12      error("Wiki parser process returned with error code " .. tostring(exitcode))
    51.1 --- a/env/ui/bargraph.lua	Mon Nov 30 12:00:00 2009 +0100
    51.2 +++ b/env/ui/bargraph.lua	Thu Dec 10 12:00:00 2009 +0100
    51.3 @@ -6,7 +6,7 @@
    51.4      content = function()
    51.5        for i, bar in ipairs(args.bars) do
    51.6          if bar.value > 0 then
    51.7 -          local value = bar.value * args.width / args.max_value / 2 
    51.8 +          local value = bar.value * args.width / args.max_value
    51.9            ui.container{
   51.10              attr = {
   51.11                style = "width: " .. tostring(value) .. "px; background-color: " .. bar.color .. ";",
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/env/ui/bargraph_legend.lua	Thu Dec 10 12:00:00 2009 +0100
    52.3 @@ -0,0 +1,32 @@
    52.4 +function ui.bargraph_legend(attr)
    52.5 +  local width = assert(attr.width)
    52.6 +  local bars = assert(attr.bars)
    52.7 +
    52.8 +  ui.container{
    52.9 +    attr = { class = "bargraph_legend" },
   52.10 +    content = function()
   52.11 +      ui.container{
   52.12 +        attr = { class = "bargraph_legend_label" },
   52.13 +        content = _"Legend:"
   52.14 +      }
   52.15 +      for i, bar in ipairs(bars) do
   52.16 +        ui.bargraph{
   52.17 +          max_value = 1,
   52.18 +          width = width,
   52.19 +          bars = {
   52.20 +            {
   52.21 +              color = bar.color,
   52.22 +              value = 1,
   52.23 +            }
   52.24 +          }
   52.25 +        }
   52.26 +        ui.container{
   52.27 +          attr = { class = "bargraph_legend_label" },
   52.28 +          content = bar.label
   52.29 +        }
   52.30 +      end
   52.31 +    end
   52.32 +  }
   52.33 +
   52.34 +  slot.put('<br style="clear: left;" />')
   52.35 +end
   52.36 \ No newline at end of file
    53.1 --- a/env/ui/tabs.lua	Mon Nov 30 12:00:00 2009 +0100
    53.2 +++ b/env/ui/tabs.lua	Thu Dec 10 12:00:00 2009 +0100
    53.3 @@ -23,6 +23,7 @@
    53.4                text = tab.label,
    53.5                params = params
    53.6              }
    53.7 +            slot.put(" ")
    53.8            end
    53.9          end
   53.10        }
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/env/util/help.lua	Thu Dec 10 12:00:00 2009 +0100
    54.3 @@ -0,0 +1,65 @@
    54.4 +function util.help(id, title)
    54.5 +  local setting_key = "liquidfeedback_frontend_hidden_help_" .. id
    54.6 +  local setting = Setting:by_pk(app.session.member.id, setting_key)
    54.7 +  if not setting then
    54.8 +    ui.container{
    54.9 +      attr = { class = "help help_visible" },
   54.10 +      content = function()
   54.11 +        ui.image{
   54.12 +          attr = { class = "help_icon" },
   54.13 +          static = "icons/16/help.png"
   54.14 +        }
   54.15 +        ui.container{
   54.16 +          attr = { class = "help_actions" },
   54.17 +          content = function()
   54.18 +            ui.link{
   54.19 +              content = _"Hide this help message",
   54.20 +              module = "help",
   54.21 +              action = "update",
   54.22 +              params = {
   54.23 +                help_ident = id,
   54.24 +                hide = true
   54.25 +              },
   54.26 +              routing = {
   54.27 +                default = {
   54.28 +                  mode = "redirect",
   54.29 +                  module = request.get_module(),
   54.30 +                  view = request.get_view(),
   54.31 +                  id = param.get_id_cgi(),
   54.32 +                  params = param.get_all_cgi()
   54.33 +                }
   54.34 +              }
   54.35 +            }
   54.36 +          end
   54.37 +        }
   54.38 +        local lang = locale.get("lang")
   54.39 +        local basepath = request.get_app_basepath() 
   54.40 +        local file_name = basepath .. "/locale/help/" .. id .. "." .. lang .. ".txt"
   54.41 +        local file = io.open(file_name)
   54.42 +        if file ~= nil then
   54.43 +          local help_text = file:read("*a")
   54.44 +          if #help_text > 0 then
   54.45 +            ui.container{
   54.46 +              attr = { class = "wiki" },
   54.47 +              content = function()
   54.48 +                slot.put(format.wiki_text(help_text))
   54.49 +              end
   54.50 +            }
   54.51 +          else
   54.52 +            ui.field.text{ value = _("Empty help text: #{id}.#{lang}.txt", { id = id, lang = lang }) }
   54.53 +          end
   54.54 +        else
   54.55 +          ui.field.text{ value = _("Missing help text: #{id}.#{lang}.txt", { id = id, lang = lang }) }
   54.56 +        end
   54.57 +      end
   54.58 +    }
   54.59 +  else
   54.60 +    if util._hidden_helps == nil then
   54.61 +      util._hidden_helps = {}
   54.62 +    end
   54.63 +    util._hidden_helps[#util._hidden_helps+1] = {
   54.64 +      id = id,
   54.65 +      title = title
   54.66 +    }
   54.67 +  end
   54.68 +end
   54.69 \ No newline at end of file
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/fastpath/Makefile	Thu Dec 10 12:00:00 2009 +0100
    55.3 @@ -0,0 +1,5 @@
    55.4 +getpic: getpic.c
    55.5 +	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
    55.6 +
    55.7 +clean::
    55.8 +	rm -f getpic
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/fastpath/getpic.c	Thu Dec 10 12:00:00 2009 +0100
    56.3 @@ -0,0 +1,157 @@
    56.4 +#include <stdlib.h>
    56.5 +#include <stdio.h>
    56.6 +#include <libpq-fe.h>
    56.7 +#include <string.h>
    56.8 +#include <regex.h>
    56.9 +#include <sys/types.h>
   56.10 +#include <sys/stat.h>
   56.11 +#include <unistd.h>
   56.12 +
   56.13 +#ifndef GETPIC_CONNINFO
   56.14 +#define GETPIC_CONNINFO "dbname=liquid_feedback"
   56.15 +#endif
   56.16 +
   56.17 +#ifndef GETPIC_DEFAULT_AVATAR
   56.18 +#define GETPIC_DEFAULT_AVATAR "/opt/liquid_feedback_testing/app/static/avatar.jpg"
   56.19 +#endif
   56.20 +
   56.21 +int main(int argc, const char * const *argv) {
   56.22 +  PGconn *conn;
   56.23 +  PGresult *dbr;
   56.24 +
   56.25 +  char *cookies = getenv("HTTP_COOKIE");
   56.26 +
   56.27 +  char *args_string;
   56.28 +  char *member_id;
   56.29 +  char *image_type;
   56.30 +
   56.31 +  char *sql_session_params[1];
   56.32 +  char *sql_member_image_params[2];
   56.33 +
   56.34 +  ssize_t start, length;
   56.35 +
   56.36 +  char *session_ident;
   56.37 +
   56.38 +  regex_t session_ident_regex;
   56.39 +  regmatch_t session_ident_regmatch[2];
   56.40 +
   56.41 +  cookies = getenv("HTTP_COOKIE");
   56.42 +
   56.43 +  args_string = getenv("QUERY_STRING");
   56.44 +
   56.45 +  if (!cookies || !args_string) {
   56.46 +    fputs("Status: 403 Access Denied\n\n", stdout);
   56.47 +    return 0;
   56.48 +  }
   56.49 +
   56.50 +  member_id   = strtok(args_string, "+");
   56.51 +  image_type  = strtok(NULL, "+");
   56.52 +
   56.53 +  sql_member_image_params[0] = member_id;
   56.54 +  sql_member_image_params[1] = image_type;
   56.55 +
   56.56 +  // get session from cookie
   56.57 +
   56.58 +  // TODO improve regex to fit better
   56.59 +  if (regcomp(&session_ident_regex, "liquid_feedback_session=([a-zA-Z0-9]+)", REG_EXTENDED) != 0) {
   56.60 +    // shouldn't happen
   56.61 +    abort();
   56.62 +  }
   56.63 +
   56.64 +  if (regexec(&session_ident_regex, cookies, 2, session_ident_regmatch, 0) != 0) {
   56.65 +    fputs("Status: 403 Access Denied\n\n", stdout);
   56.66 +    return 0;
   56.67 +  }
   56.68 +
   56.69 +  start = session_ident_regmatch[1].rm_so;
   56.70 +  length = session_ident_regmatch[1].rm_eo - session_ident_regmatch[1].rm_so;
   56.71 +
   56.72 +  session_ident = malloc(length + 1);
   56.73 +
   56.74 +  strncpy(session_ident, cookies + start, length);
   56.75 +
   56.76 +  session_ident[length] = 0;
   56.77 +
   56.78 +  sql_session_params[0] = session_ident;
   56.79 +
   56.80 +
   56.81 +  // connect to database
   56.82 +
   56.83 +  conn = PQconnectdb(GETPIC_CONNINFO);
   56.84 +  if (!conn) {
   56.85 +    fputs("Could not create PGconn structure.\n", stderr);
   56.86 +    return 1;
   56.87 +  }
   56.88 +  if (PQstatus(conn) != CONNECTION_OK) {
   56.89 +    fputs(PQerrorMessage(conn), stderr);
   56.90 +    return 1;
   56.91 +  }
   56.92 +
   56.93 +  // check session
   56.94 +  dbr = PQexecParams(conn,
   56.95 +    "SELECT NULL FROM session JOIN member ON member.id = session.member_id WHERE session.ident = $1 AND member.active",
   56.96 +    1, NULL, sql_session_params, NULL, NULL, 0
   56.97 +  );
   56.98 +
   56.99 +  if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
  56.100 +    fputs(PQresultErrorMessage(dbr), stderr);
  56.101 +    return 1;
  56.102 +  }
  56.103 +
  56.104 +  if (PQntuples(dbr) != 1) {
  56.105 +    fputs("Status: 403 Access Denied\n\n", stdout);
  56.106 +    return 0;
  56.107 +  }
  56.108 +
  56.109 +
  56.110 +  // get picture
  56.111 +  dbr = PQexecParams(conn,
  56.112 +    "SELECT content_type, data "
  56.113 +    "FROM member_image "
  56.114 +    "WHERE member_id = $1 "
  56.115 +    "AND image_type = $2 "
  56.116 +    "AND scaled "
  56.117 +    "LIMIT 1;",
  56.118 +    2, NULL, sql_member_image_params, NULL, NULL, 1
  56.119 +  );
  56.120 +
  56.121 +  if (PQresultStatus(dbr) != PGRES_TUPLES_OK) {
  56.122 +    fputs(PQresultErrorMessage(dbr), stderr);
  56.123 +		return 1;
  56.124 +  }
  56.125 +  if (PQntuples(dbr) > 1) {
  56.126 +    return 1;
  56.127 +  }
  56.128 +  fputs("Cache-Control: private; max-age=86400\n", stdout);
  56.129 +  if (PQntuples(dbr) == 0) {
  56.130 +    struct stat sb;
  56.131 +    PQclear(dbr);
  56.132 +    PQfinish(conn);
  56.133 +    fputs("Content-Type: image/jpeg\n\n", stdout);
  56.134 +    if (stat(GETPIC_DEFAULT_AVATAR, &sb)) return 1;
  56.135 +    fprintf(stdout, "Content-Length: %i\n", sb.st_size);
  56.136 +    execl("/bin/cat", "cat", GETPIC_DEFAULT_AVATAR, NULL);
  56.137 +    return 1;
  56.138 +  } else {
  56.139 +    if (PQnfields(dbr) < 0) {
  56.140 +      fputs("Too few columns returned by database.\n", stderr);
  56.141 +      return 1;
  56.142 +    }
  56.143 +    if (PQfformat(dbr, 0) != 1 || PQfformat(dbr, 1) != 1) {
  56.144 +      fputs("Database did not return data in binary format.\n", stderr);
  56.145 +      return 1;
  56.146 +    }
  56.147 +    if (PQgetisnull(dbr, 0, 0) || PQgetisnull(dbr, 0, 1)) {
  56.148 +      fputs("Unexpected NULL in database result.\n", stderr);
  56.149 +      return 1;
  56.150 +    }
  56.151 +    fputs("Content-Type: ", stdout);
  56.152 +    fprintf(stdout, "Content-Length: %i\n", PQgetlength(dbr, 0, 1));
  56.153 +    fwrite(PQgetvalue(dbr, 0, 0), PQgetlength(dbr, 0, 0), 1, stdout);
  56.154 +    fputs("\n\n", stdout);
  56.155 +    fwrite(PQgetvalue(dbr, 0, 1), PQgetlength(dbr, 0, 1), 1, stdout);
  56.156 +  }
  56.157 +  PQclear(dbr);
  56.158 +  PQfinish(conn);
  56.159 +  return 0;
  56.160 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/locale/help/area.list.de.txt	Thu Dec 10 12:00:00 2009 +0100
    57.3 @@ -0,0 +1,2 @@
    57.4 +=Themenbereiche=
    57.5 +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".
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/locale/help/area.show.de.txt	Thu Dec 10 12:00:00 2009 +0100
    58.3 @@ -0,0 +1,6 @@
    58.4 +=Themenbereich, Mitgliedschaft=
    58.5 +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.
    58.6 +=Delegation, Auto-Ablehnen=
    58.7 +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.
    58.8 +=Neues Thema=
    58.9 +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.
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/locale/help/contact.list.de.txt	Thu Dec 10 12:00:00 2009 +0100
    59.3 @@ -0,0 +1,4 @@
    59.4 +=persönliche Kontaktliste=
    59.5 +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.
    59.6 +
    59.7 +**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.
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/locale/help/delegation.new.area.de.txt	Thu Dec 10 12:00:00 2009 +0100
    60.3 @@ -0,0 +1,2 @@
    60.4 +=Delegation für diesen Themenbereich=
    60.5 +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.
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/locale/help/delegation.new.global.de.txt	Thu Dec 10 12:00:00 2009 +0100
    61.3 @@ -0,0 +1,2 @@
    61.4 +=globale Delegation=
    61.5 +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.
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/locale/help/delegation.new.issue.de.txt	Thu Dec 10 12:00:00 2009 +0100
    62.3 @@ -0,0 +1,2 @@
    62.4 +=Delegation für dieses Thema=
    62.5 +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.
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/locale/help/index.change_password.de.txt	Thu Dec 10 12:00:00 2009 +0100
    63.3 @@ -0,0 +1,2 @@
    63.4 +=Kennwort ändern=
    63.5 +Dein neues Kennwort muss mindestens 8 Zeichen lang sein.
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/locale/help/index.index.de.txt	Thu Dec 10 12:00:00 2009 +0100
    64.3 @@ -0,0 +1,8 @@
    64.4 +==Willkommen bei LiquidFeedback und auf deiner Startseite==
    64.5 +Diese blauen Boxen werden dich verfolgen bis du sie nach und nach abschaltest. Deine Startseite wird sich (hoffentlich) im Laufe der Zeit füllen: 
    64.6 +- mit deinem Profil, 
    64.7 +- den Themenbereichen, Themen und Initiativen die dich interessieren,
    64.8 +- deinen eingehenden und ausgehenden Delegationen,
    64.9 +- deinen veröffentlichten Kontakten.
   64.10 +
   64.11 +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.
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/locale/help/initiative.show.de.txt	Thu Dec 10 12:00:00 2009 +0100
    65.3 @@ -0,0 +1,10 @@
    65.4 +=Initiative, Unterstützung, Anregungen=
    65.5 +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. 
    65.6 +
    65.7 +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''. 
    65.8 +=überarbeiteter Entwurf, Umsetzungsvermerk=
    65.9 +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.
   65.10 +=wenn du nicht gehört wirst=
   65.11 +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.
   65.12 +=wenn du diese Initiative ablehnst=
   65.13 +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.
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/locale/help/issue.show.de.txt	Thu Dec 10 12:00:00 2009 +0100
    66.3 @@ -0,0 +1,12 @@
    66.4 +=Thema, Interesse=
    66.5 +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. 
    66.6 +=Delegation, Auto-Ablehnung=
    66.7 +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.
    66.8 +=Diskussionsphase=
    66.9 +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.
   66.10 +=Endabstimmung=
   66.11 +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.
   66.12 +
   66.13 +**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.
   66.14 +
   66.15 +Information zum genutzten Wahlverfahren: [http://en.wikipedia.org/wiki/Schulze_method Schulze-Methode]
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/locale/help/member.edit.de.txt	Thu Dec 10 12:00:00 2009 +0100
    67.3 @@ -0,0 +1,2 @@
    67.4 +=Profil=
    67.5 +Alle Angaben sind freiwillig. In Deinem Profil erscheinen nur die Felder, die nicht leer sind.
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/locale/help/member.edit_images.de.txt	Thu Dec 10 12:00:00 2009 +0100
    68.3 @@ -0,0 +1,5 @@
    68.4 +=Bilder=
    68.5 +Format: JPG
    68.6 +Avatar:  max. 48 x 48 Pixel, für den Avatar bevorzugt ein quadratisches Bild
    68.7 +Foto: max. 250 x 250 Pixel
    68.8 +Größere Bilder werden herunterskaliert, alle Bilder werden recodiert und von Profilen befreit.
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/locale/help/member.list.de.txt	Thu Dec 10 12:00:00 2009 +0100
    69.3 @@ -0,0 +1,4 @@
    69.4 +=Profilseiten aufrufen=
    69.5 +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.
    69.6 +=Kontaktliste erweitern=
    69.7 +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.
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/locale/help/member.show.de.txt	Thu Dec 10 12:00:00 2009 +0100
    70.3 @@ -0,0 +1,9 @@
    70.4 +=Profilseite=
    70.5 +Hier kannst du erfahren,
    70.6 +- was dieses Mitglied über sich selbst mitteilt,
    70.7 +- in welchen Themenbereichen es Mitglied ist,
    70.8 +- an welchen Themen und Initiativen es sich beteiligt
    70.9 +- welche Delegationen das Mitglied erhalten und erteilt und
   70.10 +- welche Kontakte das Mitglied veröffentlicht hat.
   70.11 +=zu den Kontakten hinzufügen=
   70.12 +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.
    72.1 --- a/locale/translations.de.lua	Mon Nov 30 12:00:00 2009 +0100
    72.2 +++ b/locale/translations.de.lua	Thu Dec 10 12:00:00 2009 +0100
    72.3 @@ -1,15 +1,15 @@
    72.4  #!/usr/bin/env lua
    72.5  return {
    72.6 -["(change)"] = "(ändern)";
    72.7 +["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht";
    72.8 +["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert";
    72.9 +["(change URL)"] = "(URL ändern)";
   72.10  ["+ #{weight}"] = false;
   72.11  ["A-Z"] = false;
   72.12  ["About"] = false;
   72.13  ["About LiquidFeedback"] = "Über LiquidFeedback";
   72.14 -["Accepted"] = "Akzeptiert";
   72.15 +["Accepted at"] = "Angenommen am/um";
   72.16  ["Active?"] = "Aktiv?";
   72.17 -["Add my interest to this issue"] = "Mein Interesse am Thema anmelden";
   72.18 -["Add my membership to this area"] = "Mitglied im Themenbereich werden";
   72.19 -["Add new draft"] = "Neuen Entwurf hinzufügen";
   72.20 +["Add my interest"] = "Mein Interesse anmelden";
   72.21  ["Add new initiative to issue"] = "Neue Initiative zum Thema hinzufügen";
   72.22  ["Add new suggestion"] = "Neue Anregung hinzufügen";
   72.23  ["Add to my contacts"] = "Zu meinen Kontakten hinzufügen";
   72.24 @@ -18,6 +18,7 @@
   72.25  ["Admin menu"] = "Admin Menü";
   72.26  ["Admin?"] = "Admin?";
   72.27  ["Administrator"] = false;
   72.28 +["Admission time"] = "Zeit für die Zulassung";
   72.29  ["Admitted"] = "zugelassen";
   72.30  ["Any"] = "Alle";
   72.31  ["Area"] = "Themenbereich";
   72.32 @@ -25,18 +26,22 @@
   72.33  ["Area delegation"] = "Area-Delegation";
   72.34  ["Area list"] = "Liste der Themenbereiche";
   72.35  ["Area successfully updated"] = "Themenbereich erfolgreich aktualisiert";
   72.36 +["Area wide delegation active"] = "Delegation für Themengebiet aktiv";
   72.37  ["Areas"] = "Themenbereiche";
   72.38  ["Author"] = "Autor";
   72.39  ["Autoreject is off."] = "Auto-Ablehnen ist aus";
   72.40  ["Autoreject is on."] = "Auto-Ablehnen ist an";
   72.41  ["Avatar"] = false;
   72.42 -["Avatar has been deleted"] = "Avatar wurde gelöscht";
   72.43 -["Avatar has been updated"] = "Avatar wurde aktualisiert";
   72.44 +["Become a member"] = "Mitglied werden";
   72.45  ["Birthday"] = "Geburtstag";
   72.46 +["Bug report"] = "Fehlerbericht";
   72.47  ["Cancel"] = "Abbrechen";
   72.48  ["Cancelled"] = "Abgebrochen";
   72.49 +["Change area delegation"] = "Delegation für Themengebiet ändern";
   72.50 +["Change global delegation"] = "Globale Delegation ändern";
   72.51 +["Change issue delegation"] = "Delegation für Thema ändern";
   72.52  ["Change password"] = "Kennwort ändern";
   72.53 -["Click here to close."] = "Zum Schließen hier klicken";
   72.54 +["Click for details"] = "Klicke für Details";
   72.55  ["Close"] = "Schließen";
   72.56  ["Closed"] = "geschlossen";
   72.57  ["Collective opinion"] = "Meinungsbild";
   72.58 @@ -50,37 +55,44 @@
   72.59  ["Created at"] = "Erzeugt am/um";
   72.60  ["Current draft"] = "Aktueller Entwurf";
   72.61  ["Degree"] = "Grad";
   72.62 -["Delegate"] = "Delegieren";
   72.63  ["Delegations"] = "Delegationen";
   72.64  ["Description"] = "Beschreibung";
   72.65  ["Details"] = "Details";
   72.66  ["Diff"] = false;
   72.67  ["Direct member count"] = "Anzahl Direktmitglieder";
   72.68 -["Direct supporter [change]"] = "Direkte Unterstützung [ändern]";
   72.69 +["Direct membership"] = "Direkte Mitgliedschaft";
   72.70  ["Discussion"] = "Diskussion";
   72.71  ["Discussion URL"] = "Diskussions-URL";
   72.72 +["Discussion time"] = "Zeit für die Diskussions";
   72.73  ["Draft"] = "Entwurf";
   72.74  ["Edit"] = "Bearbeiten";
   72.75  ["Edit draft"] = "Entwurf bearbeiten";
   72.76  ["Edit initiative"] = "Initiative bearbeiten";
   72.77  ["Edit my page"] = "Meine Seite bearbeiten";
   72.78 +["Edit my profile"] = "Mein Profil bearbeiten";
   72.79 +["Empty help text: #{id}.#{lang}.txt"] = false;
   72.80  ["Error while updating member, database reported:<br /><br /> (#{errormessage})"] = "Fehler beim aktualisieren des Mitglieds, die Datenbank berichtet folgenden Fehler:<br /><br /> (#{errormessage})";
   72.81 -["External discussion"] = "Externe Diskussion";
   72.82  ["External memberships"] = "Externe Mitgliedschaften";
   72.83  ["External posts"] = "Externe Ämter";
   72.84  ["Filter"] = false;
   72.85  ["Finished"] = "Abgeschlossen";
   72.86  ["Frozen"] = "Eingefroren";
   72.87  ["Fulfilled"] = "Erfüllt";
   72.88 -["Fully frozen"] = "Ganz eingefroren";
   72.89 +["Fully frozen at"] = "Ganz eingefroren am/um";
   72.90  ["Global delegation"] = "Globale Delegation";
   72.91 -["Half frozen"] = "Halb eingefroren";
   72.92 +["Global delegation active"] = "Globale Delegation aktiv";
   72.93 +["Half frozen at"] = "Halb eingefroren am/um";
   72.94 +["Help for: #{text}"] = "Hilfe zu: #{text}";
   72.95  ["Hide"] = "Verstecken";
   72.96 +["Hide this help message"] = "Diesen Hilfetext ausblenden";
   72.97  ["Home"] = "Startseite";
   72.98  ["Id"] = "Id";
   72.99  ["Ident number"] = "Ident-Nummer";
  72.100 +["Images"] = "Bilder";
  72.101  ["In discussion"] = "In Diskussion";
  72.102  ["Incoming delegations"] = "Eingehende Delegationen";
  72.103 +["Initiated initiatives"] = "Initierte Initiativen";
  72.104 +["Initiative quorum"] = "Quorum Inititive";
  72.105  ["Initiative successfully created"] = "Initiative erfolgreich erzeugt";
  72.106  ["Initiative successfully updated"] = "Initiative erfolgreich aktualisiert";
  72.107  ["Initiative: '#{name}'"] = "Initiative: '#{name}'";
  72.108 @@ -96,12 +108,14 @@
  72.109  ["Issue ##{id}"] = "Issue ##{id}";
  72.110  ["Issue ##{id} (#{policy_name})"] = "Thema ##{id} (#{policy_name})";
  72.111  ["Issue delegation"] = "Issue-Delegation";
  72.112 +["Issue delegation active"] = "Delegation für Thema aktiv";
  72.113  ["Issue policy"] = "Regelwerk für Thema";
  72.114 +["Issue quorum"] = "Quorum Thema";
  72.115  ["Issues"] = "Themen";
  72.116  ["Last snapshot:"] = "Letzte Auszählung:";
  72.117 +["Legend:"] = "Legende:";
  72.118  ["License"] = "Lizenz";
  72.119  ["Locked?"] = "Gesperrt?";
  72.120 -["Logged in as:"] = "Angemeldet als:";
  72.121  ["Login"] = "Anmeldung";
  72.122  ["Login successful!"] = "Anmeldung erfolgreich";
  72.123  ["Logout"] = "Abmelden";
  72.124 @@ -119,13 +133,17 @@
  72.125  ["Member list"] = "Mitgliederliste";
  72.126  ["Member login"] = "Mitglied Login";
  72.127  ["Member name"] = "Mitglied Name";
  72.128 +["Member page"] = false;
  72.129  ["Member successfully registered"] = "Mitglied erfolgreich registriert";
  72.130  ["Member successfully updated"] = "Mitglied erfolgreich aktualisert";
  72.131  ["Member: '#{login}' (#{name})"] = "Mitlied: '#{login}' (#{name})";
  72.132  ["Members"] = "Mitglieder";
  72.133 +["Membership by delegation"] = "Mitgliedschaft durch Delegation";
  72.134  ["Membership not existant"] = "Mitgliedschaft exisitert nicht";
  72.135  ["Membership removed"] = "Mitgliedschaft entfernt";
  72.136  ["Membership updated"] = "Mitgliedschaft aktualisiert";
  72.137 +["Memberships"] = "Mitgliedschaften";
  72.138 +["Missing help text: #{id}.#{lang}.txt"] = false;
  72.139  ["Mobile phone"] = "Mobiltelefon";
  72.140  ["My opinion"] = "Meine Meinung";
  72.141  ["Name"] = "Name";
  72.142 @@ -137,7 +155,9 @@
  72.143  ["New passwords is too short."] = "Das neue Kennwort ist zu kurz";
  72.144  ["Newest"] = "Neueste";
  72.145  ["Next state"] = "Nächster Zustand";
  72.146 -["No supporter [change]"] = "Keine Unterstützung (ändern)";
  72.147 +["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert";
  72.148 +["No delegation"] = "Keine Delegation";
  72.149 +["No membership at all"] = "Gar keine Mitgliedschaft";
  72.150  ["Number of incoming delegations, follow link to see more details"] = "Anzahl eingehender Delegationen, Link folgen für mehr Details";
  72.151  ["OK"] = "OK";
  72.152  ["Old draft revision"] = "Alte Revision des Entwurfs";
  72.153 @@ -150,9 +170,12 @@
  72.154  ["Outgoing delegations"] = "Ausgehende Delegationen";
  72.155  ["Password"] = "Kennwort";
  72.156  ["Phone"] = "Telefon";
  72.157 +["Photo"] = "Foto";
  72.158  ["Policy"] = "Regelwerk";
  72.159  ["Population"] = "Grundgesamtheit";
  72.160 +["Posts"] = "Ämter";
  72.161  ["Profession"] = "Beruf";
  72.162 +["Profile"] = "Profil";
  72.163  ["Publish"] = "Veröffentlichen";
  72.164  ["Published"] = "veröffentlicht";
  72.165  ["Published contacts"] = "Veröffentlichte Kontakte";
  72.166 @@ -176,9 +199,12 @@
  72.167  ["Search issues"] = "Suche Themen";
  72.168  ["Search members"] = "Suche Mitglieder";
  72.169  ["Search results for: '#{search}'"] = "Suchergebnisse für: '#{search}'";
  72.170 +["Set area delegation"] = "Delegation für Themengebiet festlegen";
  72.171  ["Set autoreject"] = "Auto-Ablehnen anschalten";
  72.172  ["Set delegation for Area '#{name}'"] = "Delegation für Themengebiet '#{name}' festlegen";
  72.173  ["Set delegation for Issue ##{number} in Area '#{area_name}'"] = "Delegation für Thema ##{number} im Themenbereich '#{area_name}' festlegen";
  72.174 +["Set global delegation"] = "Globale Delegation festlegen";
  72.175 +["Set issue delegation"] = "Delegation für Thema festlegen";
  72.176  ["Show"] = "Zeige";
  72.177  ["Show active members"] = "Zeige aktive Mitglieder";
  72.178  ["Show areas in use"] = "Zeige verwendete Themenbereiche";
  72.179 @@ -186,6 +212,7 @@
  72.180  ["Show diff"] = "Änderungen anzeigen";
  72.181  ["Show locked members"] = "Zeige gesperrte Mitglieder";
  72.182  ["Show member"] = "Mitglied anzeigen";
  72.183 +["Show other initiatives"] = "Zeige alternative Initiativen";
  72.184  ["Software"] = false;
  72.185  ["State"] = "Zustand";
  72.186  ["Statement"] = false;
  72.187 @@ -197,31 +224,34 @@
  72.188  ["Support"] = "Unterstützung";
  72.189  ["Support S+I"] = "Unterstütung S+I";
  72.190  ["Support this initiative"] = "Diese Initiative unterstützen";
  72.191 +["Supported initiatives"] = "Unterstützte Initiativen";
  72.192  ["Supporter"] = "Unterstützer";
  72.193  ["That's me!"] = "Das bin ich";
  72.194  ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht";
  72.195  ["Time left"] = "Restzeit";
  72.196 +["Title (80 chars max)"] = "Titel (max. 80 Zeichen)";
  72.197  ["Trustee"] = "Bevollmächtigter";
  72.198  ["Unknown author"] = "Unbekannter Autor";
  72.199 -["Upload avatar"] = "Avatar hochladen";
  72.200 +["Upload images"] = "Bilder hochladen";
  72.201  ["Username"] = "Benutzername";
  72.202 +["Verification time"] = "Zeit für die Überprüfung";
  72.203  ["Version"] = false;
  72.204  ["Vote later"] = "Später abstimmen";
  72.205  ["Vote now"] = "Jetzt abstimmen";
  72.206  ["Voting"] = "Abstimmung";
  72.207  ["Voting requests"] = "Abstimmanträge";
  72.208 +["Voting time"] = "Zeit für die Abstimmung";
  72.209  ["Website"] = "Webseite";
  72.210 -["X"] = false;
  72.211  ["You are already not supporting this initiative"] = "Diese Initiative hat bereits keine Unterstützung von Dir";
  72.212  ["You are already supporting the latest draft"] = "Du unterstützt bereits den neuesten Entwurf";
  72.213 -["You are interested. [more]"] = "Du bist interessiert. [mehr]";
  72.214 -["You are member. [more]"] = "Du bist Mitglied. [mehr]";
  72.215 -["You are not a member. [more]"] = "Du bist kein Mitglied. [mehr]";
  72.216 -["You are not interested. [more]"] = "Du bist nicht interessiert. [mehr]";
  72.217 +["You are currently not supporting this initiative. By adding suggestions to this initiative you will automatically become a potential supporter."] = false;
  72.218 +["You are member"] = "Du bist Mitglied";
  72.219  ["You didn't saved any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!";
  72.220  ["You have saved this member as contact"] = "Du hast das Mitglied als Kontakt gespeichert";
  72.221  ["You have saved this member as contact."] = "Du hast das Mitglied als Kontakt gespeichert.";
  72.222  ["You need to be logged in, to use this system."] = "Du musst eingeloggt sein, um das System zu benutzen";
  72.223 +["Your are interested"] = "Du bist interessiert";
  72.224 +["Your are supporter"] = "Du bist Unterstützer";
  72.225  ["Your delegation for this area has been deleted."] = "Deine Delegation für dieses Themengebiet wurde gelöscht";
  72.226  ["Your delegation for this area has been updated."] = "Deine Delegation für dieses Themengebiet wurde geändert";
  72.227  ["Your delegation for this issue has been deleted."] = "Deine Delegation für dieses Thema wurde gelöscht";
  72.228 @@ -236,23 +266,18 @@
  72.229  ["Your support has been added to this initiative"] = "Deine Unterstützung wurde der Initiative hinzugefügt";
  72.230  ["Your support has been removed from this initiative"] = "Deine Unterstützung wurde der Initiave entzogen";
  72.231  ["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert";
  72.232 -["Your vote is delegated. [more]"] = "Deine Stimme ist delegiert. [mehr]";
  72.233  ["Z-A"] = false;
  72.234 -["admission_time"] = false;
  72.235 +["all"] = "Alle";
  72.236  ["blank"] = false;
  72.237 -["delete<br /><br />"] = false;
  72.238 -["discussion_time"] = false;
  72.239 +["delete<br /><br />"] = "löschen<br /><br />";
  72.240  ["email"] = false;
  72.241 -["initiative_quorum_den"] = false;
  72.242 -["initiative_quorum_num"] = false;
  72.243 -["issue_quorum_den"] = false;
  72.244 -["issue_quorum_num"] = false;
  72.245  ["must"] = "muss";
  72.246  ["must not"] = "darf nicht";
  72.247 +["must/should"] = "muss/soll";
  72.248 +["must/should not"] = "muss/soll nicht";
  72.249  ["neutral"] = "neutral";
  72.250 +["not implemented"] = "nicht umgesetzt";
  72.251  ["should"] = "soll";
  72.252  ["should not"] = "soll nicht";
  72.253 -["verification_time"] = false;
  72.254 -["voting_time"] = false;
  72.255  ["xmpp"] = false;
  72.256  }
    73.1 --- a/model/initiative.lua	Mon Nov 30 12:00:00 2009 +0100
    73.2 +++ b/model/initiative.lua	Thu Dec 10 12:00:00 2009 +0100
    73.3 @@ -26,7 +26,6 @@
    73.4    that_key      = 'initiative_id',
    73.5    ref           = 'suggestions',
    73.6    back_ref      = 'initiative',
    73.7 -  default_order = '"id"'
    73.8  }
    73.9  
   73.10  Initiative:add_reference{
    74.1 --- a/model/member.lua	Mon Nov 30 12:00:00 2009 +0100
    74.2 +++ b/model/member.lua	Thu Dec 10 12:00:00 2009 +0100
    74.3 @@ -2,11 +2,11 @@
    74.4  Member.table = 'member'
    74.5  
    74.6  Member:add_reference{
    74.7 -  mode          = '11',
    74.8 +  mode          = '1m',
    74.9    to            = "MemberImage",
   74.10    this_key      = 'id',
   74.11    that_key      = 'member_id',
   74.12 -  ref           = 'image',
   74.13 +  ref           = 'images',
   74.14    back_ref      = 'member'
   74.15  }
   74.16  
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/model/setting.lua	Thu Dec 10 12:00:00 2009 +0100
    75.3 @@ -0,0 +1,17 @@
    75.4 +Setting = mondelefant.new_class()
    75.5 +Setting.table = 'setting'
    75.6 +Setting.primary_key = { "member_id", "key" }
    75.7 +Interest:add_reference{
    75.8 +  mode          = 'm1',
    75.9 +  to            = "Member",
   75.10 +  this_key      = 'member_id',
   75.11 +  that_key      = 'id',
   75.12 +  ref           = 'member',
   75.13 +}
   75.14 +
   75.15 +function Setting:by_pk(member_id, key)
   75.16 +  return self:new_selector()
   75.17 +    :add_where{ "member_id = ? AND key = ?", member_id, key }
   75.18 +    :optional_object_mode()
   75.19 +    :exec()
   75.20 +end
   75.21 \ No newline at end of file
    76.1 Binary file static/icons/16/book_delete.png has changed
    77.1 Binary file static/icons/16/bug.png has changed
    78.1 Binary file static/icons/16/dropdown.png has changed
    79.1 Binary file static/icons/16/error.png has changed
    80.1 Binary file static/icons/16/help.png has changed
    81.1 Binary file static/icons/16/lightning.png has changed
    82.1 Binary file static/icons/16/user_add.png has changed
    83.1 Binary file static/icons/16/user_green.png has changed
    84.1 --- a/static/style.css	Mon Nov 30 12:00:00 2009 +0100
    84.2 +++ b/static/style.css	Thu Dec 10 12:00:00 2009 +0100
    84.3 @@ -60,31 +60,27 @@
    84.4  .layout_notice, .layout_error, .layout_warning {
    84.5          background: #fff;
    84.6          font-weight: bold;
    84.7 -        right: 2ex;
    84.8          line-height: 1.7em;
    84.9 -        position: absolute;
   84.10 -        top: 6ex;
   84.11 -        width: 60ex;
   84.12          -moz-opacity:0.7;
   84.13  }
   84.14  
   84.15  .slot_notice, .slot_warning, .slot_error {
   84.16 -        padding: 2ex;
   84.17 +        padding-left: 1em;
   84.18  }
   84.19  
   84.20  .slot_notice {
   84.21 -        color: green;
   84.22 -        border: 2px solid green;
   84.23 +        background-color: #cfc;
   84.24 +        color: #040;
   84.25  }
   84.26  
   84.27  .slot_warning {
   84.28 -        color: orange;
   84.29 -        border: 2px solid orange;
   84.30 +        background-color: #fec;
   84.31 +        color: #420;
   84.32  }
   84.33  
   84.34  .slot_error {
   84.35 -        color: red;
   84.36 -        border: 2px solid red;
   84.37 +        background-color: #fcc;
   84.38 +        color: #400;
   84.39  }
   84.40  
   84.41  /*************************************************************************
   84.42 @@ -92,7 +88,6 @@
   84.43   */
   84.44  
   84.45  .topbar {
   84.46 -  margin-bottom: 1em;
   84.47    background-color: #444;
   84.48    color: #fff;
   84.49    font-size: 75%;
   84.50 @@ -161,17 +156,21 @@
   84.51   */
   84.52  
   84.53  .title_bar {
   84.54 -  border-bottom: 1px solid #000;
   84.55 +  border-bottom: 1px solid #777;
   84.56    margin-bottom: 2ex;
   84.57 +  padding-top: 1ex;
   84.58 +  padding-bottom: 0.5ex;
   84.59 +}
   84.60 +
   84.61 +.title_bar_content {
   84.62 +  margin-left: 1em;
   84.63  }
   84.64  
   84.65  .path {
   84.66    color: #444;
   84.67 -  xbackground-color: #ddd;
   84.68  }
   84.69  
   84.70  .path div {
   84.71 -  margin-left: 1em;
   84.72    font-size: 100%;
   84.73    line-height: 180%;
   84.74  }
   84.75 @@ -195,7 +194,6 @@
   84.76  }
   84.77  
   84.78  .title div {
   84.79 -  margin-left: 0.66em;
   84.80    font-weight: bold;
   84.81    font-size: 135%;
   84.82    line-height: 110%;
   84.83 @@ -205,25 +203,23 @@
   84.84    color: #fff;
   84.85  }
   84.86  
   84.87 -.avatar {
   84.88 +.member_image_avatar {
   84.89    float: left;
   84.90    margin-right: 0.5em;
   84.91 -  width: 48px;
   84.92 -  height: 48px;
   84.93  }
   84.94  
   84.95  .actions {
   84.96 -  display: inline;
   84.97    font-size: 75%;
   84.98 -  line-height: 200%;
   84.99 +  line-height: 220%;
  84.100  }
  84.101  
  84.102  .slot_actions {
  84.103 -  margin-left: 1em;
  84.104    display: inline;
  84.105  }
  84.106  
  84.107  .actions a {
  84.108 +  float: left;
  84.109 +  display: block;
  84.110    padding: 0.5ex 0.5em 0.5ex 0.0em;
  84.111    margin-right: 1em;
  84.112    vertical-align: middle;
  84.113 @@ -236,37 +232,70 @@
  84.114  .actions img {
  84.115    padding-left: 0.2em;
  84.116    padding-right: 0.2em;
  84.117 +  vertical-align: middle;
  84.118 +}
  84.119 +
  84.120 +.logo { 
  84.121 +  float: right;
  84.122 +  margin-right: 1em;
  84.123  }
  84.124  
  84.125  /*************************************************************************
  84.126   * vote info / delegation 
  84.127   */
  84.128  
  84.129 -.slot_interest,
  84.130 +.interest,
  84.131  .slot_support,
  84.132 -.slot_delegation {
  84.133 +.delegation {
  84.134    float: left;
  84.135 -  font-size: 75%;
  84.136 +  position: relative;
  84.137 +}
  84.138 +
  84.139 +.interest img,
  84.140 +.slot_support img,
  84.141 +.delegation img {
  84.142 +  padding-left: 0.2em;
  84.143 +  padding-right: 0.2em;
  84.144 +}
  84.145 +.vote_info .head {
  84.146 +  float: left;
  84.147    margin-right: 1em;
  84.148  }
  84.149  
  84.150 -.vote_info .head {
  84.151 -  line-height: 200%;
  84.152 +.interest .head_active {
  84.153 +  background-color: #dfd;
  84.154 +  border: 1px solid #8b8;
  84.155 +}
  84.156 +
  84.157 +.slot_support .head_active {
  84.158 +  background-color: #dfd;
  84.159 +  border: 1px solid #8b8;
  84.160 +}
  84.161 +
  84.162 +.delegation .head_active {
  84.163 +  background-color: #ffd;
  84.164 +  border: 1px solid #bb8;
  84.165  }
  84.166  
  84.167  .vote_info .close {
  84.168 -  background-color: #f44;
  84.169 -  float: right;
  84.170 +  position: absolute;
  84.171 +  top: 0;
  84.172 +  right: 0;
  84.173    padding: 1ex;
  84.174 +  display: block;
  84.175  }
  84.176  
  84.177  .vote_info .content {
  84.178 +  font-size: 133%;
  84.179 +  line-height: 100%;
  84.180 +  top: 3ex;
  84.181    display: none;
  84.182    position: absolute;
  84.183    z-index: 10;
  84.184    background-color: #fff;
  84.185 -  border: 2px solid #444;
  84.186 +  border: 1px solid #999;
  84.187    padding: 1em;
  84.188 +  width: 25em;
  84.189  }
  84.190  
  84.191  .vote_info .delegation_arrow {
  84.192 @@ -275,6 +304,14 @@
  84.193    vertical-align: middle;
  84.194  }
  84.195  
  84.196 +.vote_info .delegation_arrow_overridden {
  84.197 +  opacity: 0.4;
  84.198 +}
  84.199 +
  84.200 +.vote_info .delegation_scope_overridden {
  84.201 +  color: #777;
  84.202 +}
  84.203 +
  84.204  .vote_info .delegation_scope {
  84.205    display: inline;
  84.206  }
  84.207 @@ -286,14 +323,29 @@
  84.208    clear: left;
  84.209  }
  84.210  
  84.211 +.delegation_overridden .member_thumb {
  84.212 +  opacity: 0.4;
  84.213 +}
  84.214 +
  84.215  .delegation .revoke {
  84.216    margin: 0.5ex;
  84.217 +  float: right;
  84.218  }
  84.219  
  84.220  .delegation .revoke img {
  84.221    vertical-align: middle;
  84.222  }
  84.223  
  84.224 +
  84.225 +.sub_title div {
  84.226 +  border-top: 1px solid #444;
  84.227 +  padding-top: 1ex;
  84.228 +  margin-top: 1ex;
  84.229 +  font-weight: bold;
  84.230 +  font-size: 135%;
  84.231 +  line-height: 110%;
  84.232 +}
  84.233 +
  84.234  /*************************************************************************
  84.235   * Main content
  84.236   */
  84.237 @@ -315,8 +367,9 @@
  84.238  
  84.239  .ui_tabs_links a {
  84.240    padding: 1ex;
  84.241 -  margin-left: 0.5em;
  84.242 +  line-height: 200%;
  84.243    background-color: #e7e7e7;
  84.244 +  white-space: nowrap;
  84.245  }
  84.246  
  84.247  .ui_tabs_links a:hover {
  84.248 @@ -401,6 +454,25 @@
  84.249    height: 1.3ex;
  84.250  }
  84.251  
  84.252 +.bargraph_legend {
  84.253 +  margin-top: 2ex;
  84.254 +}
  84.255 +
  84.256 +.bargraph_legend .bargraph {
  84.257 +  width: 26px;
  84.258 +}
  84.259 +
  84.260 +.bargraph_legend div,
  84.261 +.bargraph_legend div div,
  84.262 +.bargraph_legend div div div {
  84.263 +  float: left;
  84.264 +}
  84.265 +
  84.266 +.bargraph_legend_label {
  84.267 +  margin-left: 0.5em;
  84.268 +  margin-right: 1em;
  84.269 +}
  84.270 +
  84.271  /*************************************************************************
  84.272   * vertical ui.form
  84.273   */
  84.274 @@ -432,7 +504,7 @@
  84.275  .vertical .ui_field_label {
  84.276    text-transform: uppercase;
  84.277    font-size: 70%;
  84.278 -  line-height: 190%;
  84.279 +  line-height: 120%;
  84.280    font-weight: bold;
  84.281    color: #777;
  84.282    width: 15em;
  84.283 @@ -631,10 +703,22 @@
  84.284  
  84.285  .member_thumb {
  84.286    text-decoration: none;
  84.287 -  min-width: 150px;
  84.288 +  width: 18em;
  84.289 +  height: 48px;
  84.290    display: block;
  84.291    float: left;
  84.292 -  border: 1px solid #ccc;
  84.293 +  border: 1px solid #999;
  84.294 +  overflow: hidden;
  84.295 +  xwhite-space: nowrap;
  84.296 +  position: relative;
  84.297 +}
  84.298 +
  84.299 +.member_thumb a{
  84.300 +  position: absolute;
  84.301 +  top: 0;
  84.302 +  left: 0;
  84.303 +  padding: 0;
  84.304 +  margin: 0;
  84.305  }
  84.306  
  84.307  .member_thumb a:hover div {
  84.308 @@ -642,25 +726,24 @@
  84.309    color: #fff;
  84.310  }
  84.311  
  84.312 -.member_thumb .flags a:hover {
  84.313 -  background-color: #444;
  84.314 -  color: #fff;
  84.315 -}
  84.316 -
  84.317  .member_thumb img {
  84.318 -  margin-right: 0.5em;
  84.319 +  padding: 0;
  84.320 +  margin: 0;
  84.321    vertical-align: bottom;
  84.322 -  float: left;
  84.323  }
  84.324  
  84.325  .member_thumb div {
  84.326 -  display: inline;
  84.327 +}
  84.328 +
  84.329 +.member_thumb .member_image {
  84.330  }
  84.331  
  84.332  .member_thumb .member_name {
  84.333 -  display: block;
  84.334 -  margin-top: 3ex;
  84.335 -  margin-right: 0.5em;
  84.336 +  position: absolute;
  84.337 +  left: 48px;
  84.338 +  top: 2ex;
  84.339 +  font-size: 100%;
  84.340 +  width: 14em;
  84.341  }
  84.342  
  84.343  .member_thumb .flags {
  84.344 @@ -668,10 +751,22 @@
  84.345    font-size: 75%;
  84.346  }
  84.347  
  84.348 -.draft_content {
  84.349 +.member_thumb .flags a{
  84.350 +  position: static;
  84.351 +  float: right;
  84.352 +}
  84.353 +
  84.354 +
  84.355 +.member .right {
  84.356 +  float: right;
  84.357 +}
  84.358 +
  84.359 +.draft_content,
  84.360 +.member_statement {
  84.361    background-color: #eee;
  84.362    border: 1px solid #ccc;
  84.363 -  padding: 1ex;
  84.364 +  padding-left: 1ex;
  84.365 +  padding-right: 1ex;
  84.366  }
  84.367  
  84.368  .diff {
  84.369 @@ -715,3 +810,73 @@
  84.370    padding: 1ex;
  84.371  }
  84.372  
  84.373 +.suggestion_fulfilled {
  84.374 +  width: 15em;
  84.375 +}
  84.376 +.suggestion_fulfilled a.action {
  84.377 +  padding-left: 0;
  84.378 +  line-height: 120%;
  84.379 +}
  84.380 +
  84.381 +.help {
  84.382 +  border: 1px solid #bcd;
  84.383 +  background-color: #def;
  84.384 +  color: #000;
  84.385 +  padding: 1ex;
  84.386 +}
  84.387 +
  84.388 +.help_visible {
  84.389 +  margin-bottom: 1ex;
  84.390 +}
  84.391 +
  84.392 +.help_visible .help_icon {
  84.393 +  float: right;
  84.394 +}
  84.395 +
  84.396 +.slot_help_hidden {
  84.397 +  float: right;
  84.398 +  margin-right: 1em;
  84.399 +}
  84.400 +
  84.401 +.help_actions {
  84.402 +  font-size: 75%;
  84.403 +  float: right;
  84.404 +}
  84.405 +
  84.406 +.help_actions a {
  84.407 +  margin-right: 1em;
  84.408 +  color: #468;
  84.409 +}
  84.410 +
  84.411 +.wiki {
  84.412 +}
  84.413 +
  84.414 +.wiki h1,
  84.415 +.wiki h2,
  84.416 +.wiki h3,
  84.417 +.wiki h4 {
  84.418 +  margin-top: 1ex;
  84.419 +  margin-bottom: 1ex;
  84.420 +}
  84.421 +
  84.422 +.wiki h1 {
  84.423 +  font-size: 150%;
  84.424 +}
  84.425 +
  84.426 +.wiki h2 {
  84.427 +  font-size: 125%;
  84.428 +}
  84.429 +
  84.430 +.wiki p {
  84.431 +  margin-top: 1ex;
  84.432 +  margin-bottom: 1ex;
  84.433 +}
  84.434 +
  84.435 +form .warning {
  84.436 +  background-color: #ffd;
  84.437 +  color: #000;
  84.438 +  border: 1px solid #dda;
  84.439 +  margin: 1ex;
  84.440 +  margin-bottom: 2ex;
  84.441 +  padding: 1ex;
  84.442 +}

Impressum / About Us