h-lame / talon

A twitter client, written in Shoes. It was used as the demo code from a presentation I gave at RubyManor. This app isn't for reals.

This URL has Read+Write access

talon / talon.rb
100644 167 lines (153 sloc) 5.463 kb
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
Shoes.setup do
  gem 'twitter'
end
 
require 'twitter'
 
Twitter::Base.class_eval do
  def end_session
    request('account/end_session.xml', :auth => true)
  end
end
 
module Talon
  def twitter_colour_to_shoes_colour(twitter_colour)
    "##{twitter_colour}"
  end
  
  def safe_profile_image_url(image_url)
    if image_url.blank?
      'default_profile_bigger.png'
    else
      image_url
    end
  end
  
  def logo
    background '#fff'
    background 'talon.jpg', :bottom => 0, :right => -20
    flow :width => '100%' do
      background '#df9', :curve => 12
      title 'Talon', :stroke => '#691FFF', :align => 'center'
    end
  end
  
  def login
    @login = stack :margin => ['10%', '15%', '10%', '0px'] do
               background '#df9', :curve => 12
               title "Who goes there?", :stroke => '#691FFF', :align => 'center'
               flow do
                 stack :width => '150px' do
                   para 'Nom de tweet', :stroke => '#691FFF'
                 end
                 @user = edit_line :width => '-170px'
               end
               flow do
                 stack :width => '150px' do
                   para 'Sekrit', :stroke => '#691FFF'
                 end
                 @pass = edit_line :width => '-170px', :secret => true
               end
               button 'That is who I am!', :width => '100%', :stroke => '#691FFF' do
                 do_login
               end
             end
  end
  
  def cached_user_lookup(screen_name)
    @user_cache ||= {}
    if @user_cache.has_key? screen_name
      @user_cache[screen_name]
    else
      @user_cache[screen_name] = @twitter.user(screen_name)
    end
  end
  
  def show_logged_in_timeline
    @logged_in_ui, @logged_in_status = show_user @logged_in_as, true
    @logged_in_timeline = stack do
                            stack :margin => ['10px', '0px', '10px', '0px'] do
                              background twitter_colour_to_shoes_colour(@logged_in_as.profile_sidebar_fill_color), :curve => 12
                              caption 'Timeline', :stroke => twitter_colour_to_shoes_colour(@logged_in_as.profile_text_color), :align => 'center'
                            end
                            @twitter.timeline.each do |status|
                              show_status cached_user_lookup(status.user.screen_name), status
                            end
                          end
  end
  
  def show_user twitter_user, is_logged_in_user = false
    user_ui = stack :margin => ['10px', '0px', '10px', '0px'] do
                background twitter_colour_to_shoes_colour(twitter_user.profile_sidebar_fill_color), :curve => 12
                flow do
                  stack :width => '120px', :margin => '10px' do
                    image safe_profile_image_url(twitter_user.profile_image_url), :width => '100px', :height => '100px'
                    if is_logged_in_user
                      button "Logout", :width => '100px' do
                        do_logout
                      end
                    end
                  end
                  stack :width => '-120px' do
                    banner twitter_user.screen_name, :stroke => twitter_colour_to_shoes_colour(twitter_user.profile_text_color)
                    subtitle "(#{twitter_user.name})", :stroke => twitter_colour_to_shoes_colour(twitter_user.profile_text_color)
                  end
                end
              end
    current_status = show_status twitter_user, twitter_user.status
    [user_ui, current_status]
  end
  
  def show_status for_user, status_info
    unless status_info.nil?
      stack :margin => '10px' do
        background twitter_colour_to_shoes_colour(for_user.profile_sidebar_fill_color), :curve => 12
        flow do
          stack :width => '60px', :margin => '10px' do
            image safe_profile_image_url(for_user.profile_image_url), :width => '50px', :height => '50px'
          end
          stack :width => '-60px' do
            caption "@#{for_user.screen_name}", :stroke => twitter_colour_to_shoes_colour(for_user.profile_text_color)
            para status_info.text, :stroke => twitter_colour_to_shoes_colour(for_user.profile_text_color)
          end
        end
      end
    end
  end
  
  def do_login
    user = @user.text
    pass = @pass.text
    # TODO - uncomment if you're using trikker locally to pretend to be twitter
    @twitter = Twitter::Base.new(user, pass) #, :api_host => '127.0.0.1')
    begin
      @twitter.verify_credentials
      @login.hide
      @logged_in_as = cached_user_lookup user
      show_logged_in_timeline
    rescue Twitter::CantConnect => e
      incorrect_login
    end
  end
  
  def incorrect_login
    if @incorrect_login_anim.nil?
      @incorrect_login_anim = animate do |i|
                                @login.displace((Math.sin(i) * 6).to_i, 0)
                              end
    end
    @incorrect_login_anim.start
    timer(2) do
      @incorrect_login_anim.stop
      @login.displace(0,0)
    end
  end
  
  def do_logout
    @login.show
    @user.text = ''
    @pass.text = ''
    @logged_in_ui.remove unless @logged_in_ui.nil?
    @logged_in_status.remove unless @logged_in_status.nil?
    @logged_in_timeline.remove unless @logged_in_timeline.nil?
    @user_cache = nil
    begin
      @twitter.end_session
    ensure
      @twitter = nil
    end
    @logged_in_as = nil
  end
end
 
Shoes.app :title => 'Talon' do
  extend Talon
  logo
  login
end