Skip to content

Instantly share code, notes, and snippets.

@jtompkins
Last active July 12, 2016 15:40
Show Gist options
  • Save jtompkins/0bc18172eeb1bf3001e0fea870c8deca to your computer and use it in GitHub Desktop.
Save jtompkins/0bc18172eeb1bf3001e0fea870c8deca to your computer and use it in GitHub Desktop.
TodoMVC - for the command line! ...in Ruby!
require_relative '../../lib/action'
require_relative '../../lib/store'
Todo = Struct.new(:text, :completed)
class CommandProcessor
def parse_command(text)
command_array = text.split(' ')
case command_array[0]
when 'add'
add_todo(command_array[1..-1].join(' '))
when 'toggle'
toggle_todo(command_array[1].to_i) unless command_array.count < 2
when 'visible'
toggle_visibility
when 'exit'
system 'clear'
exit(true)
else
add_todo(text.chomp)
end
end
def add_todo(text)
todo = Todo.new(text, false)
Rbdux::Store.dispatch(NewTodoAction.with_payload(todo))
end
def toggle_todo(id)
Rbdux::Store.dispatch(ToggleTodoAction.with_payload(id))
end
def toggle_visibility
Rbdux::Store.dispatch(ToggleVisibilityAction.empty)
end
def gather_input
puts
print '> '
parse_command(gets)
end
end
class TodoRenderer
def render
system 'clear'
puts 'TODOs'
puts '============='
puts
todos = Rbdux::Store.state[:todos]
if Rbdux::Store.state[:visibility] != :show_completed
todos = todos.reject { |t| t.completed }
end
todos.each_with_index do |t, i|
done = t.completed ? '[X]' : '[ ]'
puts "#{i + 1}. #{done} #{t.text}"
end
end
end
class TodoApp
def initialize(processor, renderer)
@processor = processor
@renderer = renderer
Rbdux::Store.subscribe { run }
end
def run
@renderer.render
@processor.gather_input
end
end
Rbdux::Action.define('toggle_todo')
Rbdux::Action.define('new_todo')
Rbdux::Action.define('toggle_visibility')
Rbdux::Store.with_state(visibility: :hide_completed, todos: [])
Rbdux::Store.reduce(ToggleVisibilityAction, :visibility) do |state, action|
state == :hide_completed ? :show_completed : :hide_completed
end
Rbdux::Store.reduce(NewTodoAction, :todos) do |state, action|
state.dup << action.payload
end
Rbdux::Store.reduce(ToggleTodoAction, :todos) do |state, action|
todos = state.dup
todo = todos[action.payload - 1]
todo.completed = !todo.completed unless todo.nil?
todos
end
TodoApp.new(CommandProcessor.new, TodoRenderer.new).run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment