Module: Timely::UI::Views::Month
- Defined in:
- lib/timely/ui/views/month.rb
Constant Summary collapse
- WEEKDAYS =
%w[Mo Tu We Th Fr Sa Su].freeze
- MINI_WIDTH =
3 extra for "WW " week number prefix
25
Class Method Summary collapse
- .format_day(day, year, month, today, selected_day, events_by_date, today_bg = 236) ⇒ Object
- .format_week(week, year, month, today, selected_day, events_by_date, today_bg = 236) ⇒ Object
-
.render_mini_month(year, month, selected_day, today, events_by_date, width = MINI_WIDTH, today_bg: 246) ⇒ Object
Render a compact mini-month calendar.
Class Method Details
.format_day(day, year, month, today, selected_day, events_by_date, today_bg = 236) ⇒ Object
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 |
# File 'lib/timely/ui/views/month.rb', line 80 def self.format_day(day, year, month, today, selected_day, events_by_date, today_bg = 236) date = Date.new(year, month, day) events = events_by_date[date] is_today = (date == today) is_selected = (selected_day && day == selected_day && date.month == today.month && date.year == today.year) || (selected_day && day == selected_day) # selected_day is only meaningful when this is the selected month # The caller controls which month gets a non-nil selected_day # Base fg color: event > sunday > saturday > default base_color = if events && !events.empty? events.first['calendar_color'] || 39 elsif date.sunday? 167 elsif date.saturday? 208 else nil end d = day.to_s.rjust(2) if is_selected && is_today base_color ? d.bd.ul.fg(base_color).bg(today_bg) : d.bd.ul.bg(today_bg) elsif is_selected base_color ? d.bd.ul.fg(base_color) : d.bd.ul elsif is_today base_color ? d.fg(base_color).bg(today_bg) : d.bg(today_bg) elsif base_color d.fg(base_color) else d end end |
.format_week(week, year, month, today, selected_day, events_by_date, today_bg = 236) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/timely/ui/views/month.rb', line 65 def self.format_week(week, year, month, today, selected_day, events_by_date, today_bg = 236) # Find week number from first non-nil day in this row first_day = week.compact.first wn = first_day ? Date.new(year, month, first_day).cweek.to_s.rjust(2) : " " cells = week.map do |day| if day.nil? " " else format_day(day, year, month, today, selected_day, events_by_date, today_bg) end end wn.fg(238) + " " + cells.join(" ") end |
.render_mini_month(year, month, selected_day, today, events_by_date, width = MINI_WIDTH, today_bg: 246) ⇒ Object
Render a compact mini-month calendar. Returns an array of strings (one per line), about 8-9 lines tall. selected_day: day number to highlight with reverse video (or nil) today: Date.today for bold+underline marking events_by_date: hash of Date => [event_hashes] for coloring event days width: available width (typically 22 chars)
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 |
# File 'lib/timely/ui/views/month.rb', line 14 def self.render_mini_month(year, month, selected_day, today, events_by_date, width = MINI_WIDTH, today_bg: 246) lines = [] # Title: centered month and year title = Date.new(year, month, 1).strftime("%B %Y") pad = [(width - title.length) / 2, 1].max lines << (" " * pad + title).bd # Weekday headers (with space for week number column) header = " " + WEEKDAYS.each_with_index.map { |d, i| s = d.rjust(2) case i when 5 then s.fg(208) # Saturday when 6 then s.fg(167) # Sunday else s.fg(245) end }.join(" ") lines << header # Build calendar grid first_day = Date.new(year, month, 1) last_day = Date.new(year, month, -1) start_offset = first_day.cwday - 1 week = [] start_offset.times { week << nil } (1..last_day.day).each do |day| week << day if week.length == 7 lines << format_week(week, year, month, today, selected_day, events_by_date, today_bg) week = [] end end # Final partial week unless week.empty? week << nil while week.length < 7 lines << format_week(week, year, month, today, selected_day, events_by_date, today_bg) end # Pad to consistent height (title + header + 6 week rows = 8 lines) while lines.length < 8 lines << " " * width end lines end |