From 52a859c762a5d0e30449b1691b58c04d9b4f3bb3 Mon Sep 17 00:00:00 2001 From: Amit Chaudhary Date: Thu, 10 Oct 2024 21:40:44 +0530 Subject: [PATCH] add welcome screen --- src/css/style.css | 274 ++++++++++++++++++++++++----------------- src/mousam.py | 56 ++++++++- src/windowLocations.py | 81 ++++++------ 3 files changed, 252 insertions(+), 159 deletions(-) diff --git a/src/css/style.css b/src/css/style.css index 92a1dff..24c3188 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1,190 +1,219 @@ .condition_label { font-size: 30px; } + .main_temp_label { font-size: 3.5rem; } -.btn_sm{ - font-size:.95rem; - padding:0.2rem .9rem; +.btn_sm { + font-size: .95rem; + padding: 0.2rem .9rem; } -.text-l1{ +.text-l1 { font-size: 4rem; } -.text-l2{ + +.text-l2 { font-size: 3.5rem; } -.text-l3{ + +.text-l3 { font-size: 3rem; } -.text-l4{ + +.text-l4 { font-size: 2.5rem; } -.text-l5{ + +.text-l5 { font-size: 2.35rem; } -.text-l6{ + +.text-l6 { font-size: 2.2rem; } -.text-l6{ + +.text-l6 { font-size: 2rem; } -.text-1{ +.text-1 { font-size: 2.2rem; } -.text-2a{ + +.text-2a { font-size: 1.8rem; } -.text-2b{ + +.text-2b { font-size: 1.5rem; } -.text-3{ + +.text-3 { font-size: 1.3rem; } -.text-3a{ + +.text-3a { font-size: 1.2rem; } -.text-4{ + +.text-4 { font-size: 1.1rem; } -.text-5{ + +.text-5 { font-size: 1.05rem; } -.text-6{ + +.text-6 { font-size: .95rem; } -.text-7{ + +.text-7 { font-size: .9rem; } -.text-8{ + +.text-8 { font-size: .85rem; } -.text-9{ + +.text-9 { font-size: .8rem; } -.title-xl{ - font-size:76px; +.title-xl { + font-size: 76px; } -.title-l{ - font-size:42px; + +.title-l { + font-size: 42px; } -.title-m{ - font-size:22px; + +.title-m { + font-size: 22px; } -.title-s{ - font-size:18px; + +.title-s { + font-size: 18px; } -.light-1{ +.light-1 { opacity: .95; } -.light-2{ + +.light-2 { opacity: .9; } -.light-3{ + +.light-3 { opacity: .8; } -.light-4{ + +.light-4 { opacity: .75; } -.light-5{ + +.light-5 { opacity: .7; } -.light-6{ + +.light-6 { opacity: .6; } -.bold-1{ +.bold-1 { font-weight: 700; } -.bold-2{ + +.bold-2 { font-weight: 600; } -.bold-3{ + +.bold-3 { font-weight: 500; } -.dark{ - color:#141414; +.dark { + color: #141414; } -.main_window{ - border-radius:13px; - border : 1px solid rgba(100, 100, 100,.3); +.main_window { + border-radius: 13px; + border: 1px solid rgba(100, 100, 100, .3); } -.overcast, .showers_scattered{ +.overcast, +.showers_scattered { background: linear-gradient(127deg, rgba(155, 155, 155, 1), rgba(0, 134, 215, 0) 100%), - linear-gradient(217deg, rgba(155, 155, 155, 1), rgba(0, 134, 215, 1) 100%), - linear-gradient(336deg, rgba(155, 155, 155, 1), rgba(0, 134, 218, 1) 100%); + linear-gradient(217deg, rgba(155, 155, 155, 1), rgba(0, 134, 215, 1) 100%), + linear-gradient(336deg, rgba(155, 155, 155, 1), rgba(0, 134, 218, 1) 100%); } -.gradient-bg{ - background:linear-gradient(0deg, rgba(237,237,237,1) 0%, rgb(203, 221, 225) 100%); +.gradient-bg { + background: linear-gradient(0deg, rgba(237, 237, 237, 1) 0%, rgb(203, 221, 225) 100%); } -.hide{ +.hide { opacity: .2; } -.transparent_0{ - background:rgba(0, 0, 0, 0); - color:white; +.transparent_0 { + background: rgba(0, 0, 0, 0); + color: white; } -.transparent_glass{ - background:rgba(150, 150, 150, .2); +.transparent_glass { + background: rgba(150, 150, 150, .2); } -.border_col{ +.border_col { border: 1px solid rgba(200, 200, 200, .1); } -.transparent_5{ - background:rgba(0, 0, 0, .35); - color:white; +.transparent_5 { + background: rgba(0, 0, 0, .35); + color: white; } -.bg-white{ +.bg-white { background-color: rgb(240, 240, 240); } -.custom_card{ - padding:.7rem .85rem; +.custom_card { + padding: .7rem .85rem; } -.bar_container{ +.bar_container { border-radius: 1rem; background-color: rgb(240, 240, 240); } -.custom_card_forecast_item{ +.custom_card_forecast_item { padding: 0rem 1.1rem; border-radius: .7rem; } -.custom_card_hourly{ +.custom_card_hourly { border-radius: .5rem; padding: .4rem .6rem; margin-top: .3rem; } -.custom_card_hourly_now{ +.custom_card_hourly_now { padding: .7rem 1.2rem; margin-top: 0rem; background-color: rgba(196, 196, 196, 0.15); } -.bg_light_grey{ + +.bg_light_grey { background-color: rgba(224, 224, 224, 0.06); } @@ -192,10 +221,11 @@ -.body{ - padding:20px; +.body { + padding: 20px; } + /* .card{ padding-left:20px; padding-right:20px; @@ -204,100 +234,124 @@ } */ -.card_info{ +.card_info { background-color: #F6635C; } -.bold{ - font-weight:600; + +.bold { + font-weight: 600; } -.title-xl{ - font-size:76px; + +.title-xl { + font-size: 76px; } -.title-m{ - font-size:22px; + +.title-m { + font-size: 22px; } -.title-s{ - font-size:18px; + +.title-s { + font-size: 18px; } + .bg-green { - background-color: #00ff00; /* Replace with your desired color */ + background-color: #00ff00; + /* Replace with your desired color */ } + .bg-orange { - background-color: #F6635C; /* Replace with your desired color */ + background-color: #F6635C; + /* Replace with your desired color */ } + .bg-pink { - background-color: #FE7BE5; /* Replace with your desired color */ + background-color: #FE7BE5; + /* Replace with your desired color */ } -.clear_sky, .few_clouds { +.clear_sky, +.few_clouds { background: linear-gradient(127deg, rgba(187, 188, 179, 1), rgba(0, 134, 218, 0) 100%), - linear-gradient(217deg, rgba(187, 188, 179, 1), rgba(0, 174, 258, 1) 100%), - linear-gradient(136deg, rgba(187, 188, 179, 1), rgba(0, 174, 258, 1) 100%); + linear-gradient(217deg, rgba(187, 188, 179, 1), rgba(0, 174, 258, 1) 100%), + linear-gradient(136deg, rgba(187, 188, 179, 1), rgba(0, 174, 258, 1) 100%); } -.overcast, .showers_scattered{ + +.overcast, +.showers_scattered { background: linear-gradient(127deg, rgba(155, 155, 155, 1), rgba(0, 134, 215, 0) 100%), - linear-gradient(217deg, rgba(155, 155, 155, 1), rgba(0, 134, 215, 1) 100%), - linear-gradient(336deg, rgba(155, 155, 155, 1), rgba(0, 134, 218, 1) 100%); + linear-gradient(217deg, rgba(155, 155, 155, 1), rgba(0, 134, 215, 1) 100%), + linear-gradient(336deg, rgba(155, 155, 155, 1), rgba(0, 134, 218, 1) 100%); } + .showers_large { background: linear-gradient(127deg, rgba(134, 137, 154, 1), rgba(134, 137, 154, 0) 100%), - linear-gradient(217deg, rgba(134, 137, 154, 1), rgba(0, 134, 218, 1) 100%), - linear-gradient(336deg, rgba(134, 137, 154, 1), rgba(0, 134, 218, 1) 100%); + linear-gradient(217deg, rgba(134, 137, 154, 1), rgba(0, 134, 218, 1) 100%), + linear-gradient(336deg, rgba(134, 137, 154, 1), rgba(0, 134, 218, 1) 100%); } -.storm{ + +.storm { background: linear-gradient(127deg, rgb(108, 123, 152), rgb(92, 92, 92)), - linear-gradient(217deg, rgb(108, 123, 152), rgb(92, 92, 92)), - linear-gradient(336deg, rgb(108, 123, 152), rgb(92, 92, 92)); + linear-gradient(217deg, rgb(108, 123, 152), rgb(92, 92, 92)), + linear-gradient(336deg, rgb(108, 123, 152), rgb(92, 92, 92)); } -.snow{ + +.snow { background: linear-gradient(135deg, rgb(40, 60, 87) 0%, rgb(80, 104, 133) 30%, rgb(137, 166, 181) 60%, rgb(187, 195, 202) 80%, rgb(187, 195, 202) 100%), - linear-gradient(45deg, rgb(200, 203, 207), rgb(212, 213, 215) 50%, rgba(255, 255, 255, 0.9)); + linear-gradient(45deg, rgb(200, 203, 207), rgb(212, 213, 215) 50%, rgba(255, 255, 255, 0.9)); } -.fog{ - background: linear-gradient(49deg, transparent 0%, rgba(212,195,156,0.43) 100%) 68% 73%/194% 147%, - linear-gradient(137deg, #9cafb0 0%, #c4c3be 70%, #c5c8b5 100%) 72% 55%/174% 123%; + +.fog { + background: linear-gradient(49deg, transparent 0%, rgba(212, 195, 156, 0.43) 100%) 68% 73%/194% 147%, + linear-gradient(137deg, #9cafb0 0%, #c4c3be 70%, #c5c8b5 100%) 72% 55%/174% 123%; } /* ------------- night --------------- */ -.clear_sky_night{ +.clear_sky_night { background: linear-gradient(127deg, rgba(45, 48, 72, 1), rgba(23, 27, 60, 0) 100%), - linear-gradient(217deg, rgba(45, 48, 72, 1), rgba(23, 27, 60, 1) 100%); + linear-gradient(217deg, rgba(45, 48, 72, 1), rgba(23, 27, 60, 1) 100%); } -.few_clouds_night{ + +.few_clouds_night { background: linear-gradient(to right bottom, #777777, #69696c, #5b5c62, #4d5057, #3e444d, #353c47, #2b3440, #222d3a, #1c2735, #172130, #121b2b, #0e1526); } -.overcast_night, .showers_scattered_night { + +.overcast_night, +.showers_scattered_night { background: linear-gradient(127deg, rgba(27, 29, 40, 1), rgba(23, 27, 60, 0) 100%), - linear-gradient(217deg, rgba(27, 29, 40, 1), rgba(46, 46, 46, 1) 100%); + linear-gradient(217deg, rgba(27, 29, 40, 1), rgba(46, 46, 46, 1) 100%); } + .showers_large_night { background: linear-gradient(127deg, rgba(27, 29, 40, 1), rgba(23, 27, 60, 0) 100%), - linear-gradient(237deg, rgba(27, 29, 40, 1), rgba(46, 46, 46, 1) 100%); + linear-gradient(237deg, rgba(27, 29, 40, 1), rgba(46, 46, 46, 1) 100%); } -.storm_night{ + +.storm_night { background: linear-gradient(127deg, rgba(50, 50, 50, 1), rgba(54, 55, 37, 1) 100%), - linear-gradient(237deg, rgba(50, 50, 50, 1), rgba(54, 55, 37, 1) 100%); + linear-gradient(237deg, rgba(50, 50, 50, 1), rgba(54, 55, 37, 1) 100%); } -.snow_night{ + +.snow_night { background: linear-gradient(127deg, rgba(50, 50, 50, 1), rgba(98, 98, 98, 1) 100%), - linear-gradient(217deg, rgba(50, 50, 50, 1), rgba(98, 98, 98, 1) 100%), - linear-gradient(336deg, rgba(50, 50, 50, 1), rgba(98, 98, 98, 1) 100%); + linear-gradient(217deg, rgba(50, 50, 50, 1), rgba(98, 98, 98, 1) 100%), + linear-gradient(336deg, rgba(50, 50, 50, 1), rgba(98, 98, 98, 1) 100%); } -.fog_night{ + +.fog_night { background: linear-gradient(127deg, rgba(28, 27, 38, 1), rgba(50, 50, 50, 0) 100%), - linear-gradient(217deg, rgba(50, 50, 50, 1), rgba(28, 27, 38, 1) 100%); -} + linear-gradient(217deg, rgba(50, 50, 50, 1), rgba(28, 27, 38, 1) 100%); +} \ No newline at end of file diff --git a/src/mousam.py b/src/mousam.py index cda635f..28adc93 100644 --- a/src/mousam.py +++ b/src/mousam.py @@ -37,13 +37,18 @@ class WeatherMainWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - + self.main_window = self self.set_default_size(settings.window_width, settings.window_height) self.connect("close-request", self.save_window_state) self.set_title("") self._use_dynamic_bg() + # Global variable : + self.added_cities = settings.added_cities + # self.added_cities variable is being used to quickly check the added_added cities so that + # there is no issue caused by dely in writing and reading in db + # Adding a button into header self.header = Adw.HeaderBar() self.header.set_css_classes(["flat"]) @@ -153,6 +158,39 @@ def show_loader(self): self.main_stack.add_named(container_loader, "loader") self.main_stack.set_visible_child_name("loader") + # =========== Create Welcome Screen ============= + def show_welcome_screen(self): + child = self.main_stack.get_child_by_name("welcome") + if child is not None: + self.main_stack.set_visible_child_name("welcome") + return + + container_welcome = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + container_welcome.set_margin_top(180) + container_welcome.set_margin_bottom(200) + + icon_mousam = Gtk.Image().new_from_icon_name("io.github.amit9838.mousam") + icon_mousam.set_hexpand(True) + icon_mousam.set_pixel_size(110) + + container_welcome.append(icon_mousam) + + welcome_label = Gtk.Label(label=_("Welcome to Mousam")) + welcome_label.set_css_classes(["text-2a", "bold-2"]) + container_welcome.append(welcome_label) + + btn_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL,halign=Gtk.Align.CENTER) + btn_box.set_margin_top(20) + add_loc_button = Gtk.Button(label="Add Location") + add_loc_button.connect("clicked", self._on_locations_clicked) + add_loc_button.set_css_classes(["pill"]) + btn_box.append(add_loc_button) + container_welcome.append(btn_box) + + + self.main_stack.add_named(container_welcome, "welcome") + self.main_stack.set_visible_child_name("welcome") + # =========== Show No Internet ============= def show_error(self, type: str = "no_internet", desc: str = ""): # Loader container @@ -197,6 +235,10 @@ def _load_weather_data(self): if not has_internet: self.show_error() return + + if len(self.added_cities) == 0: + self.show_welcome_screen() + return self.show_loader() @@ -238,9 +280,7 @@ def get_weather(self, reload_type=None, title=""): # Check if no city is added # Reset city to default if all cities are removed - if len(settings.added_cities) == 0: - settings.reset("added-cities") - settings.reset("selected-city") + # if len(settings.added_cities) == 0: child = self.main_stack.get_child_by_name("main_grid") if child is not None: @@ -335,11 +375,15 @@ def get_weather(self, reload_type=None, title=""): self.toast_overlay.add_toast(create_toast(_("Refreshed Successfully"), 1)) # ============= Refresh buttom methods ============== - def _refresh_weather(self, widget): + def _refresh_weather(self, widget=None): global updated_at # Ignore refreshing weather within 5 second - if time.time() - updated_at < 5: + if len(self.added_cities) == 0: + thread = threading.Thread(target=self._load_weather_data, name="load_data") + thread.start() + + elif time.time() - updated_at < 5: updated_at = time.time() self.toast_overlay.add_toast( create_toast(_("Refresh within 5 seconds is ignored!"), 1) diff --git a/src/windowLocations.py b/src/windowLocations.py index 37add4d..cc535c4 100644 --- a/src/windowLocations.py +++ b/src/windowLocations.py @@ -25,10 +25,9 @@ def __init__(self, application, **kwargs): self.set_default_size(600, 500) # Settings - global selected_city_item, added_cities_list, cities - selected_city_item = settings.selected_city - added_cities_list = settings.added_cities - cities = [x.split(",")[0] for x in added_cities_list] + global cities + settings.selected_city = settings.selected_city + cities = [x.split(",")[0] for x in settings.added_cities] # ============= Location Page ============= location_page = Adw.PreferencesPage() @@ -54,7 +53,7 @@ def __init__(self, application, **kwargs): self.location_grp.set_header_suffix(add_loc_btn) self.location_rows = [] - self._create_cities_list(added_cities_list) + self._create_cities_list(settings.added_cities) # =========== Location page methods ============= def _create_cities_list(self, data): @@ -63,7 +62,12 @@ def _create_cities_list(self, data): self.location_grp.remove(action_row) self.location_rows.clear() - for city in added_cities_list: + if len(settings.added_cities) == 1: + city = settings.added_cities[0].split(",") + selection_key = f"{city[-2]},{city[-1]}" + settings.selected_city = selection_key + + for city in settings.added_cities: button = Gtk.Button() button.set_icon_name("edit-delete-symbolic") button.set_css_classes(["circular"]) @@ -75,9 +79,10 @@ def _create_cities_list(self, data): orientation=Gtk.Orientation.HORIZONTAL, valign=Gtk.Align.CENTER ) selected_city_index = list( - map(lambda city: selected_city_item in city, added_cities_list) + map(lambda city: settings.selected_city in city, settings.added_cities) ).index(True) - if added_cities_list[selected_city_index] == city: + + if settings.added_cities[selected_city_index] == city: check_icon = Gtk.Image() check_icon.set_from_icon_name( "emblem-ok-symbolic" @@ -103,7 +108,6 @@ def _create_cities_list(self, data): # ========== Switch Location ============ def switch_location(self, widget): - global selected_city_item title = widget.get_title() select_cord = f"{widget.get_subtitle()}" @@ -111,10 +115,10 @@ def switch_location(self, widget): return # Switch if location is not already selected - if selected_city_item != select_cord: - selected_city_item = select_cord - settings.selected_city = selected_city_item - self._create_cities_list(added_cities_list) + if settings.selected_city != select_cord: + settings.selected_city = select_cord + settings.selected_city = settings.selected_city + self._create_cities_list(settings.added_cities) global updated_at # Ignore refreshing weather within 5 second @@ -133,7 +137,6 @@ def switch_location(self, widget): # ========== Add Location =========== def _add_location_dialog(self, application): - # Create dialog to search and add location self._dialog = Adw.PreferencesWindow() self._dialog.set_search_enabled(False) @@ -242,49 +245,41 @@ def _add_city(self, widget): loc_city = f"{modified_title},{widget.get_subtitle()}" # Add city to db if it is not already added - if loc_city not in added_cities_list: - added_cities_list.append(loc_city) - settings.added_cities = added_cities_list - self._create_cities_list(added_cities_list) - # self.application.refresh_main_ui() + if loc_city not in settings.added_cities: + self.application.added_cities = [*settings.added_cities, loc_city] + settings.added_cities = self.application.added_cities + self._create_cities_list(settings.added_cities) + if len(self.application.added_cities) == 1: + self.application._refresh_weather() self._dialog.add_toast(create_toast(_("Added - {0}").format(title), 1)) else: self._dialog.add_toast(create_toast(_("Location already added!"), 1)) + # ========== Remove City =========== def _remove_city(self, btn, widget): - global selected_city_item city = f"{widget.get_title()},{widget.get_subtitle()}" - # Don't delete city if only one item is present in the list - if len(added_cities_list) == 1: - self.add_toast(create_toast(_("Add more locations to delete!"), 1)) - return + settings.added_cities.remove(city) + new_list = list(settings.added_cities) + new_list.remove(city) + settings.added_cities = new_list + + self.application.added_cities = new_list - selected_city_index = list( - map(lambda x: selected_city_item in x, added_cities_list) - ).index(True) - s_city = added_cities_list[selected_city_index] - added_cities_list.remove(city) - - # If selected city is removed then select first city in the list - if widget.get_subtitle() == selected_city_item: - first_city = added_cities_list[0].split(",") - selected_city_item = f"{first_city[-2]},{first_city[-1]}" - settings.selected_city = selected_city_item + if len(self.application.added_cities) == 0: + self.application._refresh_weather() + + # If selected city was deleted then set first element as selected city + elif widget.get_subtitle() == settings.selected_city: + first_city = self.application.added_cities[0].split(",") + settings.selected_city = f"{first_city[-2]},{first_city[-1]}" thread = threading.Thread( target=self.application._load_weather_data, name="load_data" ) thread.start() - settings.added_cities = added_cities_list - self._create_cities_list(added_cities_list) - if s_city == city: # fetch weather only if selected_city was removed - pass - # self.application.refresh_weather(self.application) - else: - pass - # self.application.refresh_main_ui() + self._create_cities_list(settings.added_cities) self.add_toast(create_toast(_("Deleted - {0}".format(widget.get_title())), 1)) def _blank_search_page(self, status):