Skip to content

Commit

Permalink
Merge pull request #5 from soumyasen1809/weather
Browse files Browse the repository at this point in the history
Merge weather to master
  • Loading branch information
soumyasen1809 authored Sep 13, 2024
2 parents a99a5d2 + f89b95d commit f0559bf
Show file tree
Hide file tree
Showing 10 changed files with 1,314 additions and 24 deletions.
926 changes: 923 additions & 3 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ chrono = "0.4.38"
ratatui = "0.28.1"
tui-textarea = "0.6.1"
serde = { version = "1.0.209", features = ["derive"] }
serde_json = "1.0.128"
serde_json = "1.0.128"
reqwest = { version = "0.12.7", features = ["json"] }
tokio = { version = "1", features = ["full"] }
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@

RustyTUICalendar is a terminal-based calendar application written in Rust. It leverages the `chrono` crate for date and time manipulation and provides a simple and intuitive interface for viewing and managing calendar events.

![Image of the TUI interface](assets/calendar_look.png)

## Features

- Display a monthly calendar starting from Sunday
- Add and delete events
- Highlight current date
- Add and delete To-Do list
- User-friendly terminal interface
- View current weather data

## Installation

Expand All @@ -34,7 +37,7 @@ $ cargo run
```

## Features
Press F3 to start typing your commands.
Press F9 to start typing your commands. If you want to delete the entire line and startover, press `Delete`. Add `Enter` to add the command.

- **Add Events to ToDo or Calendar**: If the input specifies `todo`, it adds the event to the ToDo list. If the input specifies `app`, it adds the appointment to the calendar.
```sh
Expand All @@ -50,7 +53,9 @@ $ find, 2024-09-14
$ today
```

Additionally, press F1 and F2 to move to previous and next months respectively.
The default location for Weather is set as Guatemala. If you want to add your city of choice, replace it to the city you want. If you want to get the weather conditions for your current location, leave the string empty.

Additionally, press F1 and F2 to move to previous and next days respectively, F3 and F4 to move to previous and next months respectively and F5 and F6 to move to previous and next years respectively.

## Contributing

Expand All @@ -64,6 +69,7 @@ This project is licensed under the MIT License. See the LICENSE file for details

- chrono crate for date and time manipulation
- ratatui crate for terminal user interface
- wttr.in for weather data

## Contact

Expand Down
4 changes: 2 additions & 2 deletions assets/appointments.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
"location": "Central Park"
},
{
"date": "2024-09-06 11:00:00",
"date": "2024-09-12 11:00:00",
"event_name": "Design Meeting",
"location": "Lounge C"
},
{
"date": "2024-09-09 15:00:00",
"date": "2024-09-12 15:00:00",
"event_name": "Old Team Meeting",
"location": "Online: https://teams.microsoft.com/l/meetup-join/19%3ameeting_NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2%40thread.v2/0?context=%7b%22Tid%22%3a%22your-tenant-id%22%2c%22Oid%22%3a%22your-object-id%22%7d"
},
Expand Down
Binary file added assets/calendar_look.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 47 additions & 4 deletions src/calendar_widget.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::rc::Rc;

use chrono::{Datelike, NaiveDateTime};
use chrono::{format::StrftimeItems, Datelike, Local, NaiveDateTime};
use ratatui::{
layout::{Alignment, Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Stylize},
Expand All @@ -18,6 +18,18 @@ fn get_calendar_title_block(month: u32, year: i32) -> Block<'static> {
.title(format!(" Calendar - {:?} / {:?} ", month, year))
}

fn get_calendar_title_text() -> Paragraph<'static> {
let current_time = Local::now()
.time()
.format_with_items(StrftimeItems::new("%H:%M:%S"));
Paragraph::new(current_time.to_string())
.fg(Color::LightRed)
// .add_modifier(Modifier::BOLD)
.block(Block::new().padding(Padding::new(0, 2, 0, 0)))
.alignment(Alignment::Right)
.wrap(Wrap { trim: true })
}

fn get_calendar_text(calendar_text: String) -> Paragraph<'static> {
Paragraph::new(calendar_text)
.fg(Color::DarkGray)
Expand Down Expand Up @@ -52,16 +64,34 @@ fn get_appointment_block(day: u32, month: u32, year: i32) -> Block<'static> {
))
}

fn get_weather_block(city_name: &str) -> Block<'static> {
Block::default()
.borders(Borders::ALL)
.fg(Color::Magenta)
.title(format!("Weather for {:?}", city_name))
}

fn get_weather_text(weather_text: String) -> Paragraph<'static> {
Paragraph::new(weather_text)
.fg(Color::Magenta)
.block(Block::new().padding(Padding::new(5, 2, 2, 2)))
.alignment(Alignment::Left)
.wrap(Wrap { trim: true })
}

pub fn main_calendar_layout(
frame: &mut Frame,
frame: &mut Frame<'_>,
main_layout: &Rc<[Rect]>,
calendar_date: &mut NaiveDateTime,
weather_text: &String,
city_name: &str,
) {
let mut calendar = Calendar::new();
let day = calendar_date.day();
let year = calendar_date.year();
let month = calendar_date.month();

let calendar_title_text = get_calendar_title_text();
let calendar_text = calendar.generate_calendar_text(calendar_date);
let appointment_text = calendar.generate_appointment_text(*calendar_date);

Expand All @@ -77,14 +107,27 @@ pub fn main_calendar_layout(
)
.split(main_layout[0]);

let month_weather_layout = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(60), Constraint::Percentage(40)].to_vec())
.split(layout[1]);

let calendar_block = get_calendar_title_block(month, year);
let month_days_block = get_calendar_month_block();
let appointment_block = get_appointment_block(day, month, year);
let weather_block = get_weather_block(city_name);

frame.render_widget(calendar_block.clone(), layout[0]);
frame.render_widget(calendar_title_text, layout[0]);

frame.render_widget(month_days_block.clone(), month_weather_layout[0]);
frame.render_widget(get_calendar_text(calendar_text), month_weather_layout[0]);

frame.render_widget(month_days_block.clone(), layout[1]);
frame.render_widget(get_calendar_text(calendar_text), layout[1]);
frame.render_widget(weather_block.clone(), month_weather_layout[1]);
frame.render_widget(
get_weather_text(weather_text.to_string()),
month_weather_layout[1],
);

frame.render_widget(appointment_block.clone(), layout[2]);
frame.render_widget(get_appointment_text(appointment_text), layout[2]);
Expand Down
42 changes: 34 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::io::{self, stdout};

use calendar_data::Calendar;
use chrono::{Months, NaiveDateTime};
use chrono::{Days, Months, NaiveDateTime};
use ratatui::{
backend::CrosstermBackend,
crossterm::{
Expand All @@ -15,16 +15,19 @@ use ratatui::{
};

use tui_textarea::{Input, TextArea};
use weather::Weather;
use widgets::app_layout;

pub mod calendar_data;
pub mod calendar_widget;
pub mod logic;
pub mod to_do_data;
pub mod to_do_widget;
pub mod weather;
pub mod widgets;

fn main() -> io::Result<()> {
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
enable_raw_mode()?;
stdout().execute(EnterAlternateScreen)?;
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
Expand All @@ -34,22 +37,29 @@ fn main() -> io::Result<()> {
.fg(Color::DarkGray)
.add_modifier(Modifier::RAPID_BLINK);
input_todo_textarea.set_line_number_style(style);
input_todo_textarea.set_placeholder_text("F3 to start entering events ... \n");
input_todo_textarea.set_placeholder_text("F9 to start entering events ... \n");

let calendar = Calendar::new();
let mut calendar_date = calendar.current_date;
let mut is_writing_mode = false;
let mut should_quit = false;

let city_name = "Guatemala";
let weather = Weather::default();
let weather_text = weather.generate_weather_text(city_name).await?;

while !should_quit {
terminal.draw(|f| {
app_layout(
f,
&mut input_todo_textarea,
&mut calendar_date,
is_writing_mode,
)
&weather_text,
city_name,
);
})?;

should_quit = handle_events(
&mut input_todo_textarea,
&mut calendar_date,
Expand All @@ -72,20 +82,36 @@ fn handle_events(
match key.code {
KeyCode::Esc => return Ok(true),
KeyCode::F(1) => {
// Go to the prev day
*calendar_data = calendar_data.checked_sub_days(Days::new(1)).unwrap();
}
KeyCode::F(2) => {
// Go to the next day
*calendar_data = calendar_data.checked_add_days(Days::new(1)).unwrap();
}
KeyCode::F(3) => {
// Go to the prev month
*calendar_data = calendar_data.checked_sub_months(Months::new(1)).unwrap();
}
KeyCode::F(2) => {
KeyCode::F(4) => {
// Go to the next month
*calendar_data = calendar_data.checked_add_months(Months::new(1)).unwrap();
}
KeyCode::F(3) => {
KeyCode::F(5) => {
// Go to the prev year
*calendar_data = calendar_data.checked_sub_months(Months::new(12)).unwrap();
}
KeyCode::F(6) => {
// Go to the next year
*calendar_data = calendar_data.checked_add_months(Months::new(12)).unwrap();
}
KeyCode::F(9) => {
if *is_writing_mode {
// If writing mode is ON, F3 turns it OFF
// If writing mode is ON, F9 turns it OFF
*is_writing_mode = false
} else {
textarea.set_placeholder_text("");
// If writing mode is OFF, F3 turns it ON
// If writing mode is OFF, F9 turns it ON
*is_writing_mode = true
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/to_do_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn write_user_input_to_json(
if parts_input[1].clone().len() < 19 {
// If less than 19, then it is in NaiveDate format => need to change it to NaiveDateTime
let date_time_formated =
String::from(parts_input[1].clone()) + &String::from(" 00:00:00"); // converting string to NaiveDateTime format
parts_input[1].clone() + &String::from(" 00:00:00"); // converting string to NaiveDateTime format
*calendar_date = string_to_naive_date(&date_time_formated);
} else {
*calendar_date = string_to_naive_date(&parts_input[1].clone());
Expand Down
Loading

0 comments on commit f0559bf

Please sign in to comment.