🏡 index : quine-global-labs/bazaar.git

using Gtk 4.0;
using Gio 2.0;
using Gdk 4.0;
using Adw 1;

template $BzWindow: Adw.ApplicationWindow {
  title: bind $format_title(navigation_view.visible-page as <Adw.NavigationPage>.title);
  default-width: 1220;
  default-height: 900;
  width-request: 360;
  height-request: 294;

  ShortcutController {
    Shortcut {
      trigger: "Escape";
      action: "action(escape)";
    }

    Shortcut {
      trigger: "Back";
      action: "action(escape)";
    }

    Shortcut {
      trigger: "BackSpace";
      action: "action(escape)";
    }

    Shortcut {
      trigger: "<ctrl>g";
      action: "action(escape)";
    }
  }

  DropTarget drop_target {
    actions: copy;

    accept => $drop_accept_cb(template);
    drop => $drop_cb(template);
  }

  content: Gtk.Overlay window_overlay {
    child: Adw.ToolbarView {
      content: Adw.BreakpointBin split_breakpoint_bin {
        width-request: 360;
        height-request: 450;

        child: Adw.ToastOverlay toasts {
          child: Adw.NavigationView navigation_view {
            pop-on-escape: false;

            Adw.NavigationPage {
              tag: "main";
              // Translators: Please treat "Bazaar" as a brand name and avoid translating.
              title: _("Bazaar");

              child: Adw.ToolbarView toolbar_view {
                top-bar-style: flat;
                bottom-bar-style: flat;
                reveal-bottom-bars: false;

                content: Stack main_stack {
                  StackPage {
                    name: "loading";

                    child: Box {
                      halign: fill;
                      valign: center;
                      orientation: vertical;
                      spacing: 6;
                      tooltip-text: bind template.state as <$BzStateInfo>.background-task-label;

                      Adw.Spinner {
                        width-request: 64;
                        height-request: 64;
                        margin-bottom: 18;
                      }

                      Label {
                        label: _("Refreshing");
                        wrap: true;
                        justify: center;
                        margin-bottom: 24;

                        styles [
                          "title-3",
                        ]
                      }
                    };
                  }

                  StackPage {
                    name: "main";

                    child: Adw.ViewStack main_view_stack {
                      Adw.ViewStackPage {
                        name: "browse";
                        title: _("Curated");
                        icon-name: "star-outline-rounded-symbolic";
                        visible: bind template.state as <$BzStateInfo>.curated-provider as <$BzContentProvider>.has-inputs;

                        child: $BzCuratedView browse {
                          state: bind template.state as <$BzStateInfo>;
                          browse-flathub => $browse_flathub_cb(template);
                        };
                      }

                      Adw.ViewStackPage {
                        name: "flathub";
                        title: _("Explore");
                        icon-name: "explore-symbolic";

                        child: $BzFlathubPage {
                          state: bind template.state as <$BzStateInfo>;
                          open-search => $open_search_cb(template);
                        };
                      }

                      Adw.ViewStackPage {
                        name: "installed";
                        // Translators: .
                        title: _("Library");
                        icon-name: "library-symbolic";
                        badge-number: bind template.state as <$BzStateInfo>.available-updates as <Gio.ListStore>.n-items;
                        needs-attention: bind template.state as <$BzStateInfo>.available-updates as <Gio.ListStore>.n-items;

                        child: $BzLibraryPage library_page {
                          state: bind template.state;
                          transactions: bind template.state as <$BzStateInfo>.transaction-manager;
                          model: bind template.state as <$BzStateInfo>.all-installed-entry-groups;
                          update => $update_cb(template);
                        };
                      }

                      Adw.ViewStackPage {
                        name: "search";
                        title: _("Search");
                        icon-name: "system-search-symbolic";

                        child: $BzSearchPage search_page {
                          state: bind template.state;
                        };
                      }
                    };
                  }
                };

                [top]
                Box {
                  orientation: vertical;

                  Adw.HeaderBar top_header_bar {
                    [start]
                    Box {
                      styles [
                        "bz-debug",
                      ]

                      orientation: horizontal;
                      spacing: 6;
                      visible: bind template.state as <$BzStateInfo>.debug-mode;

                      Button {
                        // Translators: Please treat "Bazaar" as a brand name and avoid translating.
                        tooltip-text: "Open Bazaar Inspector";
                        icon-name: "bug-symbolic";
                        action-name: "app.bazaar-inspector";
                      }
                    }

                    [start]
                    MenuButton {
                      visible: bind try {template.state as <$BzStateInfo>.auth-state as <$BzAuthState>.authenticated, false};
                      menu-model: account_menu;

                      styles [
                        "circular",
                        "flat",
                      ]

                      child: Adw.Avatar {
                        size: 24;
                        show-initials: true;
                        text: bind template.state as <$BzStateInfo>.auth-state as <$BzAuthState>.name;
                        custom-image: bind try { $choose_object(template.state as <$BzStateInfo>.auth-state as <$BzAuthState>.paintable as <$BzAsyncTexture>.loaded, template.state as <$BzStateInfo>.auth-state as <$BzAuthState>.paintable , null as <Gdk.Paintable>), null as <Gdk.Paintable>};
                      };
                    }

                    [start]
                    Revealer {
                      transition-type: crossfade;
                      transition-duration: 750;
                      margin-start: 8;
                      reveal-child: bind $logical_and($invert_boolean(template.state as <$BzStateInfo>.busy) as <bool>, $invert_boolean($is_null(template.state as <$BzStateInfo>.background-task-label) as <bool>) as <bool>) as <bool>;
                      child: Adw.Spinner {
                        width-request: 16;
                        height-request: 16;
                        tooltip-text: bind template.state as <$BzStateInfo>.background-task-label;
                      };
                    }

                    [title]
                    Box {
                      Adw.ViewSwitcher {
                        stack: main_view_stack;
                        policy: wide;
                        visible: bind $invert_boolean(template.state as <$BzStateInfo>.busy) as <bool>;
                      }
                      Label {
                        // Translators: Please treat "Bazaar" as a brand name and avoid translating.
                        label: _("Bazaar");
                        visible: bind template.state as <$BzStateInfo>.busy as <bool>;
                        styles [
                          "title",
                        ]
                      }
                    }

                    [end]
                    MenuButton {
                      primary: true;
                      icon-name: "open-menu-symbolic";
                      tooltip-text: _("Main Menu");
                      menu-model: primary_menu;
                    }
                  }

                  Adw.Banner {
                    styles [
                      "bz-donations-banner",
                    ]

                    revealed: bind $invert_boolean(template.state as <$BzStateInfo>.donation-prompt-dismissed as <bool>) as <bool>;
                    // Translators: Please treat "Bazaar" as a brand name and avoid translating.
                    title: _("You are running a new version of Bazaar!");
                    button-label: _("See What's New");
                    action-name: "app.donate";
                  }

                  Adw.Banner {
                    sensitive: bind $invert_boolean(template.state as <$BzStateInfo>.syncing as <bool>) as <bool>;
                    revealed: bind $logical_and($invert_boolean(template.state as <$BzStateInfo>.metered_connection as <bool>) as <bool>, $logical_and(template.state as <$BzStateInfo>.have_connection as <bool>, $invert_boolean(template.state as <$BzStateInfo>.online as <bool>) as <bool>) as <bool>) as <bool>;
                    title: _("You have a network connection but are viewing a cached version of Flathub");
                    button-label: _("Refresh Manually");
                    button-clicked => $sync_cb(template);
                  }

                  Adw.Banner {
                    sensitive: bind $invert_boolean(template.state as <$BzStateInfo>.syncing as <bool>) as <bool>;
                    revealed: bind $logical_and(
                        $invert_boolean(template.state as <$BzStateInfo>.recently-synced as <bool>) as <bool>,
                        $logical_and(template.state as <$BzStateInfo>.metered_connection as <bool>, template.state as <$BzStateInfo>.have_connection as <bool>) as <bool>
                    ) as <bool>;
                    title: _("Network connection is metered — automatic refreshes disabled");
                    button-label: _("Refresh Manually");
                    button-clicked => $sync_cb(template);
                  }
                }

                [bottom]
                Adw.ViewSwitcherBar {
                  stack: main_view_stack;
                  reveal: true;
                  visible: bind $invert_boolean(template.state as <$BzStateInfo>.busy) as <bool>;
                }
              };
            }
          };
        };

        Adw.Breakpoint {
          condition ("max-width: 700px")

          setters {
            top_header_bar.title-widget: null;
            toolbar_view.reveal-bottom-bars: true;
          }

          apply => $breakpoint_apply_cb(template);
          unapply => $breakpoint_unapply_cb(template);
        }
      };
    };
  };
}

menu primary_menu {
  section {
    item {
      // Translators: Please treat "Bazaar" as a brand name and avoid translating.
      label: _("_Donate to Bazaar");
      action: "app.donate";
    }
  }
  section {
    item {
      label: _("_Refresh");
      action: "app.sync-remotes";
    }
    item {
      label: _("_Login With Flathub");
      action: "app.flathub-login";
      hidden-when: "action-disabled";
    }

    item {
      label: _("_Manage Leftover User Data");
      action: "window.user-data";
    }
  }
  section {
    item {
      label: _("_Preferences");
      action: "app.preferences";
    }

    item {
      label: _("_Keyboard Shortcuts");
      action: "app.shortcuts";
    }

    item {
      // Translators: Please treat "Bazaar" as a brand name and avoid translating.
      label: _("_About Bazaar");
      action: "app.about";
    }
  }
  section {
    item {
      // Translators: Please treat "Bazaar" as a brand name and avoid translating.
      label: _("_Quit Bazaar");
      action: "app.quit";
    }
  }
}

menu debug_menu {
  section {
    item {
      // Translators: Please treat "Bazaar" as a brand name and avoid translating.
      label: "Open Bazaar Inspector";
      action: "app.bazaar-inspector";
    }
  }
}

menu account_menu {
  section {
    item {
      label: _("Favorites");
      action: "app.flathub-favorites";
    }
  }

  section {
    item {
      label: _("Log Out");
      action: "app.flathub-logout";
    }
  }
}