public
Description: Tracks is a GTD(TM) web application, built with Ruby on Rails
Homepage: http://www.rousette.org.uk/projects/
Clone URL: git://github.com/bsag/tracks.git
Click here to lend your support to: tracks and make a donation at www.pledgie.com !
fixes for mobile view and for recurring todos

* fixed redirect to last page instead of /mobile after adding a new todo using 
mobile interface
* fixed adding new todo to tickler instead of home after marking a todo 
belonging an active recurring todo complete
lrbalt (author)
Mon Aug 04 07:13:51 -0700 2008
commit  db86df5497f72b109f815c94a24ac9af3948349d
tree    33fdc79e565cb042821f08028c61b0aaacb91c63
parent  c6dc3fcd5b413c23ad25045fa4de05fff1ff708d
...
144
145
146
 
147
148
149
...
144
145
146
147
148
149
150
0
@@ -144,6 +144,7 @@ class ContextsController < ApplicationController
0
       @not_done = @not_done_todos.select {|t| t.context_id == @context.id } 
0
       @down_count = @not_done.size 
0
       cookies[:mobile_url]=request.request_uri
0
+      @mobile_from_context = @context.id
0
       render :action => 'mobile_show_context'
0
     end
0
   end
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
0
@@ -1,282 +1,283 @@
0
-class ProjectsController < ApplicationController
0
-
0
-  helper :application, :todos, :notes
0
-  before_filter :set_source_view
0
-  before_filter :set_project_from_params, :only => [:update, :destroy, :show, :edit]
0
-  before_filter :default_context_filter, :only => [:create, :update]
0
-  skip_before_filter :login_required, :only => [:index]
0
-  prepend_before_filter :login_or_feed_token_required, :only => [:index]
0
-  session :off, :only => :index, :if => Proc.new { |req| ['rss','atom','txt'].include?(req.parameters[:format]) }
0
-
0
-  def index
0
-    @projects = current_user.projects(true)
0
-    if params[:projects_and_actions]
0
-      projects_and_actions
0
-    else      
0
-      @contexts = current_user.contexts(true)
0
-      init_not_done_counts(['project'])
0
-      if params[:only_active_with_no_next_actions]
0
-        @projects = @projects.select { |p| p.active? && count_undone_todos(p) == 0 }
0
-      end
0
-      init_project_hidden_todo_counts(['project'])
0
-      respond_to do |format|
0
-        format.html  &render_projects_html
0
-        format.m     &render_projects_mobile
0
-        format.xml   { render :xml => @projects.to_xml( :except => :user_id )  }
0
-        format.rss   &render_rss_feed
0
-        format.atom  &render_atom_feed
0
-        format.text  &render_text_feed
0
-      end
0
-    end
0
-  end
0
-
0
-  def projects_and_actions
0
-    @projects = @projects.select { |p| p.active? }
0
-    respond_to do |format|
0
-      format.text  { 
0
-        render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime::TEXT
0
-      }
0
-    end
0
-  end
0
-
0
-  def show
0
-    init_data_for_sidebar unless mobile?
0
-    @projects = current_user.projects
0
-    @page_title = "TRACKS::Project: #{@project.name}"
0
-    @project.todos.send :with_scope, :find => { :include => [:context, :tags] } do
0
-      @not_done = @project.not_done_todos(:include_project_hidden_todos => true)
0
-      @deferred = @project.deferred_todos.sort_by { |todo| todo.show_from }
0
-      @done = @project.done_todos
0
-    end
0
-    
0
-    @max_completed = current_user.prefs.show_number_completed
0
-    
0
-    @count = @not_done.size
0
-    @down_count = @count + @deferred.size 
0
-    @next_project = current_user.projects.next_from(@project)
0
-    @previous_project = current_user.projects.previous_from(@project)
0
-    @default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
0
-    respond_to do |format|
0
-      format.html
0
-      format.m     &render_project_mobile
0
-      format.xml   { render :xml => @project.to_xml( :except => :user_id )  }
0
-    end
0
-  end
0
-  
0
-  # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type:
0
-  # application/xml'
0
-  #                    -u username:password
0
-  #                    -d '<request><project><name>new project_name</name></project></request>'
0
-  #                    http://our.tracks.host/projects
0
-  # 
0
-  def create
0
-    if params[:format] == 'application/xml' && params['exception']
0
-      render_failure "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
0
-      return
0
-    end
0
-    @project = current_user.projects.build
0
-    params_are_invalid = true
0
-    if (params['project'] || (params['request'] && params['request']['project']))
0
-      @project.attributes = params['project'] || params['request']['project']
0
-      params_are_invalid = false
0
-    end
0
-    @go_to_project = params['go_to_project']
0
-    @saved = @project.save
0
-    @project_not_done_counts = { @project.id => 0 }
0
-    @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
0
-    @contexts = current_user.contexts
0
-    respond_to do |format|
0
-      format.js { @down_count = current_user.projects.size }
0
-      format.xml do
0
-        if @project.new_record? && params_are_invalid
0
-          render_failure "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
0
-        elsif @project.new_record?
0
-          render_failure @project.errors.full_messages.join(', ')
0
-        else
0
-          head :created, :location => project_url(@project)
0
-        end
0
-      end
0
-    end
0
-  end
0
-
0
-  # Edit the details of the project
0
-  # 
0
-  def update
0
-    params['project'] ||= {}
0
-    if params['project']['state']
0
-      @state_changed = @project.state != params['project']['state']
0
-      logger.info "@state_changed: #{@project.state} == #{params['project']['state']} != #{@state_changed}"
0
-      @project.transition_to(params['project']['state'])
0
-      params['project'].delete('state')
0
-    end
0
-    success_text = if params['field'] == 'name' && params['value']
0
-      params['project']['id'] = params['id'] 
0
-      params['project']['name'] = params['value'] 
0
-    end
0
-    @project.attributes = params['project']
0
-    if @project.save
0
-      if boolean_param('wants_render')
0
-        if (@project.hidden?)
0
-          @project_project_hidden_todo_counts = Hash.new
0
-          @project_project_hidden_todo_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
0
-        else
0
-          @project_not_done_counts = Hash.new
0
-          @project_not_done_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
0
-        end
0
-        @contexts = current_user.contexts
0
-        @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
0
-        @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'")
0
-        @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'")
0
-        render :template => 'projects/update.js.rjs'
0
-        return
0
-      elsif boolean_param('update_status')
0
-        render :template => 'projects/update_status.js.rjs'
0
-        return
0
-      elsif boolean_param('update_default_context')
0
-        @initial_context_name = @project.default_context.name 
0
-        render :template => 'projects/update_default_context.js.rjs'
0
-        return
0
-      else
0
-        render :text => success_text || 'Success'
0
-        return
0
-      end
0
-    else
0
-      notify :warning, "Couldn't update project"
0
-      render :text => ''
0
-      return
0
-    end
0
-    render :template => 'projects/update.js.rjs'
0
-  end
0
-  
0
-  def edit
0
-    @contexts = current_user.contexts
0
-    respond_to do |format|
0
-      format.js
0
-    end
0
-  end
0
-  
0
-  def destroy
0
-    @project.destroy
0
-    @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
0
-    @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'")
0
-    @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'")
0
-    respond_to do |format|
0
-      format.js { @down_count = current_user.projects.size }
0
-      format.xml { render :text => "Deleted project #{@project.name}" }
0
-    end
0
-  end
0
-  
0
-  def order
0
-    project_ids = params["list-active-projects"] || params["list-hidden-projects"] || params["list-completed-projects"]    
0
-    projects = current_user.projects.update_positions( project_ids )
0
-    render :nothing => true
0
-  rescue
0
-    notify :error, $!
0
-    redirect_to :action => 'index'
0
-  end
0
-  
0
-  def alphabetize
0
-    @state = params['state']
0
-    @projects = current_user.projects.alphabetize(:state => @state) if @state
0
-    @contexts = current_user.contexts
0
-    init_not_done_counts(['project'])
0
-  end
0
-  
0
-  protected
0
-    
0
-  def render_projects_html
0
-    lambda do
0
-      @page_title = "TRACKS::List Projects"
0
-      @count = current_user.projects.size 
0
-      @active_projects = @projects.select{ |p| p.active? }
0
-      @hidden_projects = @projects.select{ |p| p.hidden? }
0
-      @completed_projects = @projects.select{ |p| p.completed? }
0
-      @no_projects = @projects.empty?
0
-      @projects.cache_note_counts
0
-      @new_project = current_user.projects.build
0
-      render
0
-    end
0
-  end
0
-
0
-  def render_projects_mobile
0
-    lambda do
0
-      @active_projects = @projects.select{ |p| p.active? }
0
-      @hidden_projects = @projects.select{ |p| p.hidden? }
0
-      @completed_projects = @projects.select{ |p| p.completed? }
0
-      @down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size 
0
-      cookies[:mobile_url]=request.request_uri
0
-      render :action => 'index_mobile'
0
-    end
0
-  end
0
-    
0
-  def render_project_mobile
0
-    lambda do
0
-      if @project.default_context.nil?
0
-        @project_default_context = "This project does not have a default context"
0
-      else
0
-        @project_default_context = "The default context for this project is "+
0
-          @project.default_context.name
0
-      end
0
-      cookies[:mobile_url]=request.request_uri
0
-      render :action => 'project_mobile'
0
-    end
0
-  end
0
-
0
-  def render_rss_feed
0
-    lambda do
0
-      render_rss_feed_for @projects, :feed => feed_options,
0
-        :item => { :title => :name, :description => lambda { |p| summary(p) } }
0
-    end
0
-  end
0
-
0
-  def render_atom_feed
0
-    lambda do
0
-      render_atom_feed_for @projects, :feed => feed_options,
0
-        :item => { :description => lambda { |p| summary(p) },
0
-        :title => :name,
0
-        :author => lambda { |p| nil } }
0
-    end
0
-  end
0
-    
0
-  def feed_options
0
-    Project.feed_options(current_user)
0
-  end
0
-
0
-  def render_text_feed
0
-    lambda do
0
-      init_project_hidden_todo_counts(['project'])
0
-      render :action => 'index', :layout => false, :content_type => Mime::TEXT
0
-    end
0
-  end
0
-        
0
-  def set_project_from_params
0
-    @project = current_user.projects.find_by_params(params)
0
-  end
0
-    
0
-  def set_source_view
0
-    @source_view = params['_source_view'] || 'project'
0
-  end
0
-    
0
-  def default_context_filter
0
-    p = params['project']
0
-    p = params['request']['project'] if p.nil? && params['request']
0
-    p = {} if p.nil?
0
-    default_context_name = p['default_context_name']
0
-    p.delete('default_context_name')
0
-
0
-    unless default_context_name.blank?
0
-      default_context = Context.find_or_create_by_name(default_context_name)
0
-      p['default_context_id'] = default_context.id
0
-    end
0
-  end
0
-
0
-  def summary(project)
0
-    project_description = ''
0
-    project_description += sanitize(markdown( project.description )) unless project.description.blank?
0
-    project_description += "<p>#{count_undone_todos_phrase(p)}. "
0
-    project_description += "Project is #{project.state}."
0
-    project_description += "</p>"
0
-    project_description
0
-  end
0
-
0
-end
0
+class ProjectsController < ApplicationController
0
+
0
+  helper :application, :todos, :notes
0
+  before_filter :set_source_view
0
+  before_filter :set_project_from_params, :only => [:update, :destroy, :show, :edit]
0
+  before_filter :default_context_filter, :only => [:create, :update]
0
+  skip_before_filter :login_required, :only => [:index]
0
+  prepend_before_filter :login_or_feed_token_required, :only => [:index]
0
+  session :off, :only => :index, :if => Proc.new { |req| ['rss','atom','txt'].include?(req.parameters[:format]) }
0
+
0
+  def index
0
+    @projects = current_user.projects(true)
0
+    if params[:projects_and_actions]
0
+      projects_and_actions
0
+    else      
0
+      @contexts = current_user.contexts(true)
0
+      init_not_done_counts(['project'])
0
+      if params[:only_active_with_no_next_actions]
0
+        @projects = @projects.select { |p| p.active? && count_undone_todos(p) == 0 }
0
+      end
0
+      init_project_hidden_todo_counts(['project'])
0
+      respond_to do |format|
0
+        format.html  &render_projects_html
0
+        format.m     &render_projects_mobile
0
+        format.xml   { render :xml => @projects.to_xml( :except => :user_id )  }
0
+        format.rss   &render_rss_feed
0
+        format.atom  &render_atom_feed
0
+        format.text  &render_text_feed
0
+      end
0
+    end
0
+  end
0
+
0
+  def projects_and_actions
0
+    @projects = @projects.select { |p| p.active? }
0
+    respond_to do |format|
0
+      format.text  { 
0
+        render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime::TEXT
0
+      }
0
+    end
0
+  end
0
+
0
+  def show
0
+    init_data_for_sidebar unless mobile?
0
+    @projects = current_user.projects
0
+    @page_title = "TRACKS::Project: #{@project.name}"
0
+    @project.todos.send :with_scope, :find => { :include => [:context, :tags] } do
0
+      @not_done = @project.not_done_todos(:include_project_hidden_todos => true)
0
+      @deferred = @project.deferred_todos.sort_by { |todo| todo.show_from }
0
+      @done = @project.done_todos
0
+    end
0
+    
0
+    @max_completed = current_user.prefs.show_number_completed
0
+    
0
+    @count = @not_done.size
0
+    @down_count = @count + @deferred.size 
0
+    @next_project = current_user.projects.next_from(@project)
0
+    @previous_project = current_user.projects.previous_from(@project)
0
+    @default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
0
+    respond_to do |format|
0
+      format.html
0
+      format.m     &render_project_mobile
0
+      format.xml   { render :xml => @project.to_xml( :except => :user_id )  }
0
+    end
0
+  end
0
+  
0
+  # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type:
0
+  # application/xml'
0
+  #                    -u username:password
0
+  #                    -d '<request><project><name>new project_name</name></project></request>'
0
+  #                    http://our.tracks.host/projects
0
+  # 
0
+  def create
0
+    if params[:format] == 'application/xml' && params['exception']
0
+      render_failure "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
0
+      return
0
+    end
0
+    @project = current_user.projects.build
0
+    params_are_invalid = true
0
+    if (params['project'] || (params['request'] && params['request']['project']))
0
+      @project.attributes = params['project'] || params['request']['project']
0
+      params_are_invalid = false
0
+    end
0
+    @go_to_project = params['go_to_project']
0
+    @saved = @project.save
0
+    @project_not_done_counts = { @project.id => 0 }
0
+    @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
0
+    @contexts = current_user.contexts
0
+    respond_to do |format|
0
+      format.js { @down_count = current_user.projects.size }
0
+      format.xml do
0
+        if @project.new_record? && params_are_invalid
0
+          render_failure "Expected post format is valid xml like so: <request><project><name>project name</name></project></request>."
0
+        elsif @project.new_record?
0
+          render_failure @project.errors.full_messages.join(', ')
0
+        else
0
+          head :created, :location => project_url(@project)
0
+        end
0
+      end
0
+    end
0
+  end
0
+
0
+  # Edit the details of the project
0
+  # 
0
+  def update
0
+    params['project'] ||= {}
0
+    if params['project']['state']
0
+      @state_changed = @project.state != params['project']['state']
0
+      logger.info "@state_changed: #{@project.state} == #{params['project']['state']} != #{@state_changed}"
0
+      @project.transition_to(params['project']['state'])
0
+      params['project'].delete('state')
0
+    end
0
+    success_text = if params['field'] == 'name' && params['value']
0
+      params['project']['id'] = params['id'] 
0
+      params['project']['name'] = params['value'] 
0
+    end
0
+    @project.attributes = params['project']
0
+    if @project.save
0
+      if boolean_param('wants_render')
0
+        if (@project.hidden?)
0
+          @project_project_hidden_todo_counts = Hash.new
0
+          @project_project_hidden_todo_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
0
+        else
0
+          @project_not_done_counts = Hash.new
0
+          @project_not_done_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
0
+        end
0
+        @contexts = current_user.contexts
0
+        @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
0
+        @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'")
0
+        @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'")
0
+        render :template => 'projects/update.js.rjs'
0
+        return
0
+      elsif boolean_param('update_status')
0
+        render :template => 'projects/update_status.js.rjs'
0
+        return
0
+      elsif boolean_param('update_default_context')
0
+        @initial_context_name = @project.default_context.name 
0
+        render :template => 'projects/update_default_context.js.rjs'
0
+        return
0
+      else
0
+        render :text => success_text || 'Success'
0
+        return
0
+      end
0
+    else
0
+      notify :warning, "Couldn't update project"
0
+      render :text => ''
0
+      return
0
+    end
0
+    render :template => 'projects/update.js.rjs'
0
+  end
0
+  
0
+  def edit
0
+    @contexts = current_user.contexts
0
+    respond_to do |format|
0
+      format.js
0
+    end
0
+  end
0
+  
0
+  def destroy
0
+    @project.destroy
0
+    @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
0
+    @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'")
0
+    @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'")
0
+    respond_to do |format|
0
+      format.js { @down_count = current_user.projects.size }
0
+      format.xml { render :text => "Deleted project #{@project.name}" }
0
+    end
0
+  end
0
+  
0
+  def order
0
+    project_ids = params["list-active-projects"] || params["list-hidden-projects"] || params["list-completed-projects"]    
0
+    projects = current_user.projects.update_positions( project_ids )
0
+    render :nothing => true
0
+  rescue
0
+    notify :error, $!
0
+    redirect_to :action => 'index'
0
+  end
0
+  
0
+  def alphabetize
0
+    @state = params['state']
0
+    @projects = current_user.projects.alphabetize(:state => @state) if @state
0
+    @contexts = current_user.contexts
0
+    init_not_done_counts(['project'])
0
+  end
0
+  
0
+  protected
0
+    
0
+  def render_projects_html
0
+    lambda do
0
+      @page_title = "TRACKS::List Projects"
0
+      @count = current_user.projects.size 
0
+      @active_projects = @projects.select{ |p| p.active? }
0
+      @hidden_projects = @projects.select{ |p| p.hidden? }
0
+      @completed_projects = @projects.select{ |p| p.completed? }
0
+      @no_projects = @projects.empty?
0
+      @projects.cache_note_counts
0
+      @new_project = current_user.projects.build
0
+      render
0
+    end
0
+  end
0
+
0
+  def render_projects_mobile
0
+    lambda do
0
+      @active_projects = @projects.select{ |p| p.active? }
0
+      @hidden_projects = @projects.select{ |p| p.hidden? }
0
+      @completed_projects = @projects.select{ |p| p.completed? }
0
+      @down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size 
0
+      cookies[:mobile_url]=request.request_uri
0
+      render :action => 'index_mobile'
0
+    end
0
+  end
0
+    
0
+  def render_project_mobile
0
+    lambda do
0
+      if @project.default_context.nil?
0
+        @project_default_context = "This project does not have a default context"
0
+      else
0
+        @project_default_context = "The default context for this project is "+
0
+          @project.default_context.name
0
+      end
0
+      cookies[:mobile_url]=request.request_uri
0
+      @mobile_from_project = @project.id
0
+      render :action => 'project_mobile'
0
+    end
0
+  end
0
+
0
+  def render_rss_feed
0
+    lambda do
0
+      render_rss_feed_for @projects, :feed => feed_options,
0
+        :item => { :title => :name, :description => lambda { |p| summary(p) } }
0
+    end
0
+  end
0
+
0
+  def render_atom_feed
0
+    lambda do
0
+      render_atom_feed_for @projects, :feed => feed_options,
0
+        :item => { :description => lambda { |p| summary(p) },
0
+        :title => :name,
0
+        :author => lambda { |p| nil } }
0
+    end
0
+  end
0
+    
0
+  def feed_options
0
+    Project.feed_options(current_user)
0
+  end
0
+
0
+  def render_text_feed
0
+    lambda do
0
+      init_project_hidden_todo_counts(['project'])
0
+      render :action => 'index', :layout => false, :content_type => Mime::TEXT
0
+    end
0
+  end
0
+        
0
+  def set_project_from_params
0
+    @project = current_user.projects.find_by_params(params)
0
+  end
0
+    
0
+  def set_source_view
0
+    @source_view = params['_source_view'] || 'project'
0
+  end
0
+    
0
+  def default_context_filter
0
+    p = params['project']
0
+    p = params['request']['project'] if p.nil? && params['request']
0
+    p = {} if p.nil?
0
+    default_context_name = p['default_context_name']
0
+    p.delete('default_context_name')
0
+
0
+    unless default_context_name.blank?
0
+      default_context = Context.find_or_create_by_name(default_context_name)
0
+      p['default_context_id'] = default_context.id
0
+    end
0
+  end
0
+
0
+  def summary(project)
0
+    project_description = ''
0
+    project_description += sanitize(markdown( project.description )) unless project.description.blank?
0
+    project_description += "<p>#{count_undone_todos_phrase(p)}. "
0
+    project_description += "Project is #{project.state}."
0
+    project_description += "</p>"
0
+    project_description
0
+  end
0
+
0
+end
...
33
34
35
 
 
 
 
 
 
36
37
38
...
71
72
73
74
 
75
76
77
...
33
34
35
36
37
38
39
40
41
42
43
44
...
77
78
79
 
80
81
82
83
0
@@ -33,6 +33,12 @@ class TodosController < ApplicationController
0
       format.m {
0
         @new_mobile = true
0
         @return_path=cookies[:mobile_url]
0
+        @mobile_from_context = current_user.contexts.find_by_id(params[:from_context]) if params[:from_context]
0
+        @mobile_from_project = current_user.projects.find_by_id(params[:from_project]) if params[:from_project]
0
+        if params[:from_project] && !params[:from_context]
0
+          # we have a project but not a context -> use the default context
0
+          @mobile_from_context = @mobile_from_project.default_context
0
+        end
0
         render :action => "new" 
0
       }
0
     end
0
@@ -71,7 +77,7 @@ class TodosController < ApplicationController
0
         # todo: use function for this fixed path
0
         @return_path='/mobile' if @return_path.nil?
0
         if @saved
0
-          redirect_to mobile_abbrev_url
0
+          redirect_to @return_path
0
         else
0
           @projects = current_user.projects.find(:all)
0
           @contexts = current_user.contexts.find(:all)
...
114
115
116
117
 
118
119
120
121
 
122
123
124
...
114
115
116
 
117
118
 
119
 
120
121
122
123
0
@@ -114,11 +114,10 @@ module TodosHelper
0
     tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
0
     # removed the link. TODO: add link to mobile view of tagged actions
0
     tag_list = tags_except_starred.collect{|t| 
0
-      "<span class=\"tag #{t.name.gsub(' ','-')}\">" + 
0
+      "<span class=\"tag\">" + 
0
         link_to(t.name, {:action => "tag", :controller => "todos", :id => t.name+".m"}) + 
0
-        #        link_to(t.name, formatted_tag_path(t, :m)) +
0
       "</span>"}.join('')
0
-    "<span class='tags'>#{tag_list}</span>"
0
+    "<span class=\"tags\">#{tag_list}</span>"
0
   end
0
   
0
   def deferred_due_date
...
1
 
 
 
 
 
2
3
4
...
10
11
12
13
 
14
15
16
...
 
1
2
3
4
5
6
7
8
...
14
15
16
 
17
18
19
20
0
@@ -1,4 +1,8 @@
0
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
0
+<%
0
+    new_todo_params = {}
0
+    new_todo_params[:from_project] = @mobile_from_project if @mobile_from_project
0
+    new_todo_params[:from_context] = @mobile_from_context if @mobile_from_context
0
+-%><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
0
 <html xmlns="http://www.w3.org/1999/xhtml">
0
 <head>
0
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
0
@@ -10,7 +14,7 @@
0
       if !@prefs.nil? -%>
0
 <h1><span class="count"><%= @down_count %></span> <%= 
0
         user_time.strftime(@prefs.title_date_format) -%></h1>
0
-<%=     (link_to("0-Add new action", formatted_new_todo_path(:m))+" | ") unless @new_mobile -%>
0
+<%=     (link_to("0-Add new action", formatted_new_todo_path(:m, new_todo_params))+" | ") unless @new_mobile -%>
0
 <%=     (link_to("1-Home", formatted_todos_path(:m))+" | ") unless @home -%>
0
 <%=     (link_to("2-Contexts", formatted_contexts_path(:m))+" | ") -%>
0
 <%=     (link_to("3-Projects", formatted_projects_path(:m))+" | ") -%>
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
0
@@ -1,26 +1,40 @@
0
-<% @tag_list_text = "" 
0
-   @tag_list_text = tag_list_text if @todo -%>
0
-<span class="errors">
0
-<%= error_messages_for("todo") %>
0
-</span>
0
-<% this_year = user_time.to_date.strftime("%Y").to_i
0
-if parent_container_type == 'show_mobile' -%>
0
-<p><label for="todo_done">Done?</label>&nbsp;<%= check_box_tag("done", 1, @todo && @todo.completed?, "tabindex" => 1) %></p>
0
-<% end -%>
0
-<h2><label for="todo_description">Description</label></h2>
0
-<%= text_field( "todo", "description", "tabindex" => 2) %>
0
-<h2><label for="todo_notes">Notes</label></h2>
0
-<%= text_area( "todo", "notes", "cols" => 30, "rows" => 5, "tabindex" => 3) %>
0
-<h2><label for="todo_context_id">Context</label></h2>
0
-<%= collection_select( "todo", "context_id", @contexts, "id", "name", {"tabindex" => 4} ) %>
0
-<h2><label for="todo_project_id">Project</label></h2>
0
-<%= collection_select( "todo", "project_id", @projects, "id", "name",
0
-                          {:include_blank => true}, {"tabindex" => 5} ) %>
0
-<h2><label for="tag_list">Tags (separate with commas)</label></h2>
0
-<%= text_field_tag "tag_list", @tag_list_text, :size => 30, :tabindex => 6 %> 
0
-<h2><label for="todo_due">Due</label></h2>
0
-<%= date_select("todo", "due", :order => [:day, :month, :year],
0
-                    :start_year => this_year, :include_blank => true) %>
0
-<h2><label for="todo_show_from">Show from</label></h2>
0
-<%= date_select("todo", "show_from", :order => [:day, :month, :year], 
0
-                    :start_year => this_year, :include_blank => true) %>
0
+<% @tag_list_text = "" 
0
+   @tag_list_text = tag_list_text if @todo -%>
0
+<span class="errors">
0
+<%= error_messages_for("todo") %>
0
+</span>
0
+<% this_year = user_time.to_date.strftime("%Y").to_i
0
+if parent_container_type == 'show_mobile' -%>
0
+<p><label for="todo_done">Done?</label>&nbsp;<%= check_box_tag("done", 1, @todo && @todo.completed?, "tabindex" => 1) %></p>
0
+<% end -%>
0
+<h2><label for="todo_description">Description</label></h2>
0
+<%= text_field( "todo", "description", "tabindex" => 2) %>
0
+<h2><label for="todo_notes">Notes</label></h2>
0
+<%= text_area( "todo", "notes", "cols" => 30, "rows" => 5, "tabindex" => 3) %>
0
+<h2><label for="todo_context_id">Context</label></h2>
0
+<%= unless @mobile_from_context
0
+  collection_select( "todo", "context_id", @contexts, "id", "name", {}, {"tabindex" => 4} ) 
0
+else
0
+  select_tag("todo[context_id]", options_from_collection_for_select(
0
+    @contexts, "id", "name", @mobile_from_context.id), 
0
+    {"id" => :todo_context_id, :tabindex => 4} )
0
+end %>
0
+<h2><label for="todo_project_id">Project</label></h2>
0
+<%= unless @mobile_from_project
0
+  collection_select( "todo", "project_id", @projects, "id", "name",
0
+                          {:include_blank => true}, {"tabindex" => 5} )
0
+else
0
+  # manually add blank option since :include_blank does not work 
0
+  # with options_from_collection_for_select
0
+  select_tag("todo[project_id]", "<option value=\"\"></option>"+options_from_collection_for_select(
0
+    @projects, "id", "name", @mobile_from_project.id), 
0
+    {"id" => :todo_project_id, :tabindex => 5} )
0
+end %>
0
+<h2><label for="tag_list">Tags (separate with commas)</label></h2>
0
+<%= text_field_tag "tag_list", @tag_list_text, :size => 30, :tabindex => 6 %> 
0
+<h2><label for="todo_due">Due</label></h2>
0
+<%= date_select("todo", "due", :order => [:day, :month, :year],
0
+                    :start_year => this_year, :include_blank => true) %>
0
+<h2><label for="todo_show_from">Show from</label></h2>
0
+<%= date_select("todo", "show_from", :order => [:day, :month, :year], 
0
+                    :start_year => this_year, :include_blank => true) %>
...
17
18
19
20
 
21
22
23
24
25
 
26
27
28
...
17
18
19
 
20
21
22
23
24
 
25
26
27
28
0
@@ -17,12 +17,12 @@ if @saved
0
     end
0
     
0
     # show new todo if the completed todo was recurring
0
-    unless @new_recurring_todo.nil?
0
+    unless @new_recurring_todo.nil? || @new_recurring_todo.deferred?
0
       page.call "todoItems.ensureVisibleWithEffectAppear", item_container_id(@new_recurring_todo)
0
       page.insert_html :bottom, item_container_id(@new_recurring_todo), :partial => 'todos/todo', :locals => { :todo => @new_recurring_todo, :parent_container_type => parent_container_type }
0
       page.visual_effect :highlight, dom_id(@new_recurring_todo, 'line'), {'startcolor' => "'#99ff99'"}      
0
     else
0
-      page.notify :notice, "There is no next action after the recurring action you just finished. The recurrence is completed", 6.0 unless @recurring_todo.nil?
0
+      page.notify :notice, "There is no next action after the recurring action you just finished. The recurrence is completed", 6.0 unless @new_recurring_todo.deferred?
0
     end
0
     
0
   else

Comments