Class: TaskTree::Tasky

Inherits:
Object
  • Object
show all
Defined in:
lib/tasktree/tasky.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Tasky

Returns a new instance of Tasky.



10
11
12
13
14
15
16
17
18
19
# File 'lib/tasktree/tasky.rb', line 10

def initialize(options)
  @output = options.output || 'default.json'
  gem_base_dir = Gem.loaded_specs["task-tree"].full_gem_path
  @font_path = options.figlet_font || "#{gem_base_dir}/fonts/larry3d"
  @prompt = TTY::Prompt.new
  @tree_root = Tree::TreeNode.new('__', '__')
  @current_node = @tree_root
  @screen = TTY::Screen
  @animations = options.animations || false
end

Instance Method Details

#draw_task(task) ⇒ Object



295
296
297
298
299
# File 'lib/tasktree/tasky.rb', line 295

def draw_task(task)
  width = @screen.width - 2
  text = `figlet -f #{@font_path} -c -w #{width} #{task}`
  text
end

#handle_action(action) ⇒ Object



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
# File 'lib/tasktree/tasky.rb', line 61

def handle_action(action)
  case action
  when :clean
    print_current
    @prompt.keypress('_')
  when :add
    prompt_and_add_task
    print_current(action)
    save_state
  when :up
    move_up
    print_current(action)
  when :down
    move_down
    print_current(action)
  when :print
    print_tree
    print_current(action)
  when :complete
    set_as_complete
    print_current(action)
    save_state
  when :previous
    move_previous
    print_current(action)
  when :next
    move_next
    print_current(action)
  when :last_sibling
    move_last
    print_current
  when :first_sibling
    move_first
    print_current
  when :pommo
  when :pommo
    start_pommo
  end
end

#join_page(left, right) ⇒ Object



256
257
258
259
260
261
262
263
# File 'lib/tasktree/tasky.rb', line 256

def join_page(left, right)
  return nil if left.length != right.length
  joined = []
  left.length.times do |i|
    joined.push(left[i] + right[i]) unless left.empty?
  end
  joined
end

#load_tree(json_hash) ⇒ Object



313
314
315
316
317
# File 'lib/tasktree/tasky.rb', line 313

def load_tree(json_hash)
  node = Tree::TreeNode.new(json_hash['name'], json_hash['content'])
  json_hash['children'].each { |h| node << load_tree(h) } unless json_hash['children'].nil?
  node
end

#move_downObject



133
134
135
136
137
138
# File 'lib/tasktree/tasky.rb', line 133

def move_down
  @current_node = @current_node.first_child unless @current_node.first_child.nil?
  if @current_node.content == 'complete'
    move_up unless move_next || move_previous
  end
end

#move_first(current = @current_node) ⇒ Object



171
172
173
174
175
176
177
178
# File 'lib/tasktree/tasky.rb', line 171

def move_first(current=@current_node)
  first = current.first_sibling
  if first.content == 'complete'
    first = move_next(first)
  else
    @current_node = first
  end
end

#move_last(current = @current_node) ⇒ Object



162
163
164
165
166
167
168
169
# File 'lib/tasktree/tasky.rb', line 162

def move_last(current=@current_node)
  last = current.last_sibling
  if last.content == 'complete'
    last = move_previous(last)
  else
    @current_node = last
  end
end

#move_next(nxt = @current_node) ⇒ Object



151
152
153
154
155
156
157
158
159
160
# File 'lib/tasktree/tasky.rb', line 151

def move_next(nxt=@current_node)
  return false if nxt.is_only_child? || nxt.is_last_sibling?
  nxt = nxt.next_sibling
  if nxt.content == 'complete'
    nxt = move_next(nxt)
  else
    @current_node = nxt
  end
  true
end

#move_previous(prev = @current_node) ⇒ Object



140
141
142
143
144
145
146
147
148
149
# File 'lib/tasktree/tasky.rb', line 140

def move_previous(prev=@current_node)
  return false if prev.is_only_child? || prev.is_first_sibling?
  prev = prev.previous_sibling
  if prev.content == 'complete'
    prev = move_previous(prev)
  else
    @current_node = prev
  end
  true
end

#move_upObject



129
130
131
# File 'lib/tasktree/tasky.rb', line 129

def move_up
  @current_node = @current_node.parent if !@current_node.parent.nil?
end


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
# File 'lib/tasktree/tasky.rb', line 188

def print_current(direction=nil)
  if !@animations
    direction = nil
  end
  empty_row = ""
  @previous_page = @screen.height.times.map { empty_row } if @previous_page.nil?
  page = @previous_page
  task = draw_task(@current_node.content)
  task_lines = task.split("\n")
  case direction
  when :down
    blank = 0
    @screen.height.times do |line_num|
      start_task = @screen.height - task_lines.length
      line = line_num >= start_task ? task_lines[line_num - start_task] : empty_row
      blank +=1 if line == empty_row
      puts page
      sleep 0.01
      # add after
      page.push(line)
      # remove first
      page = page[1..-1]
    end
  when :up
    task_lines.reverse!
    @screen.height.times do |line_num|
      line = task_lines.length > line_num ? task_lines[line_num] :  empty_row
      puts page
      sleep 0.01
      # add before
      page.unshift(line)
      # remove last
      page = page[0..-2]
    end
  when :next
    blank_lines = (@screen.height-task_lines.length).times.map { empty_row }
    right_page = blank_lines + task_lines
    joined = join_page(page, right_page)
    speed = 3
    ((@screen.width * 0.8).to_i / speed).times do |col_num|
      joined = remove_page_col(joined, speed: speed)
      print_from_left(joined)
      # TODO: need to regulate speed here, moving previous is very slow
      sleep 0.005
    end
    page = right_page
  when :previous
    blank_lines = (@screen.height-task_lines.length).times.map { empty_row }
    left_page = blank_lines + task_lines
    joined = join_page(left_page, page)
    speed = 3
    ((@screen.width * 0.666).to_i / speed).times do |col_num|
      joined = remove_page_col(joined, reverse: true, speed: speed)
      print_from_right(joined)
      sleep 0.003
    end
    page = left_page
    puts page
  else
    task = draw_task(@current_node.content)
    task_lines = task.split("\n")
    blank_lines = (@screen.height-task_lines.length).times.map { empty_row }
    page = blank_lines + task_lines
    puts task
  end
  @previous_page = page
end


265
266
267
268
269
270
# File 'lib/tasktree/tasky.rb', line 265

def print_from_left(page)
  to_print = []
  end_num = @screen.width-1
  page.each { |line| to_print.push(line[0..end_num]) }
  puts to_print
end


272
273
274
275
276
# File 'lib/tasktree/tasky.rb', line 272

def print_from_right(page)
  to_print = []
  page.each { |line| to_print.push(line[-@screen.width..-1]) }
  puts to_print
end


111
112
113
# File 'lib/tasktree/tasky.rb', line 111

def print_tree
  @tree_root.print_tree
end

#prompt_and_add_taskObject



180
181
182
183
184
185
186
# File 'lib/tasktree/tasky.rb', line 180

def prompt_and_add_task
  new_task = @prompt.ask('what to add?')
  return if new_task.nil? || new_task.empty?
  new_node = Tree::TreeNode.new(new_task, new_task)
  @current_node << new_node
  @current_node = new_node
end

#remove_page_col(page, options = {}) ⇒ Object



278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/tasktree/tasky.rb', line 278

def remove_page_col(page, options={})
  new_page = []
  speed = options[:speed] || 1
  page.each do |line|
    if line.empty?
      new_page.push(line)
    else
      if options[:reverse]
        new_page.push(line[0..-speed])
      else
        new_page.push(line[speed..-1])
      end
    end
  end
  new_page
end

#restore_stateObject



305
306
307
308
309
310
311
# File 'lib/tasktree/tasky.rb', line 305

def restore_state
  return unless File.exist?(@output)
  data = File.read(@output)
  parsed_data = JSON.parse(data)
  @tree_root = load_tree(parsed_data)
  @current_node = @tree_root
end

#save_stateObject



301
302
303
# File 'lib/tasktree/tasky.rb', line 301

def save_state
  File.write(@output, @tree_root.to_json)
end

#select_with_menuObject



115
116
117
118
119
120
121
122
# File 'lib/tasktree/tasky.rb', line 115

def select_with_menu
  selected = @prompt.select("Current level:") do |menu|
    @current_node.children.each do |c|
      menu.choice c.name, c
    end
  end
  @current_node = selected
end

#set_as_completeObject



124
125
126
127
# File 'lib/tasktree/tasky.rb', line 124

def set_as_complete
  @current_node.content = 'complete'
  move_next
end

#startObject



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
# File 'lib/tasktree/tasky.rb', line 33

def start
  return unless verify_dependencies?
  restore_state
  print_current

  action = :quit
  loop do
    action = @prompt.expand('Next action?') do |q|
      q.choice key: 'a', name: 'add', value: :add
      q.choice key: 'u', name: 'up', value: :up
      q.choice key: 'd', name: 'down', value: :down
      q.choice key: 'n', name: 'next', value: :next
      q.choice key: 'p', name: 'previous', value: :previous
      q.choice key: 'P', name: 'print', value: :print
      q.choice key: 'c', name: 'complete', value: :complete
      q.choice key: 'q', name: 'quit', value: :quit
      q.choice key: 'x', name: 'quit without saving', value: :exit
      q.choice key: 's', name: 'start pommodoro timer', value: :pommo
      q.choice key: 'l', name: 'clean display', value: :clean
      q.choice key: '$', name: 'last', value: :last_sibling
      q.choice key: '_', name: 'first', value: :first_sibling
    end
    handle_action(action)
    break if action == :quit || action == :exit
  end
  save_state if action == :quit
end

#start_pommoObject



101
102
103
104
105
106
107
108
109
# File 'lib/tasktree/tasky.rb', line 101

def start_pommo
  minutes = @prompt.ask('how many minutes?', convert: :int)
  bar = TTY::ProgressBar.new('[:bar]', total: minutes*6)
  (minutes*6).times do
    sleep(10)
    bar.advance(1)
    # TODO: check for quit or pause?
  end
end

#verify_dependencies?Boolean

Returns:

  • (Boolean)


21
22
23
24
25
26
27
28
29
30
31
# File 'lib/tasktree/tasky.rb', line 21

def verify_dependencies?
  out, err, = Open3.capture3('which figlet')
  if err.include?('no figlet') || err.include?('not found')
    puts ''
    puts '---------------------------------------------------------------'
    puts '--> unfortunately you need to install figlet for this to work  '
    puts '---------------------------------------------------------------'
    return false
  end
  true
end