using Gtk 4.0; using Gio 2.0; using Adw 1; template $BzFullView: Adw.Bin { child: Adw.ToolbarView { [top] Adw.HeaderBar header_bar { overflow: hidden; [title] Revealer { reveal-child: bind $is_scrolled_down(main_scroll.vadjustment as .value) as ; transition-type: slide_up; transition-duration: 500; overflow: visible; child: Label { label: bind template.entry-group as <$BzEntryGroup>.title; styles ["title"] }; } } content: Adw.ViewStack stack { enable-transitions: false; Adw.ViewStackPage { name: "loading"; child: Adw.Bin {}; } Adw.ViewStackPage { name: "content"; child: Adw.BreakpointBin { width-request: 360; height-request: 100; Adw.Breakpoint { condition ("max-width: 700px") setters { context_bar.orientation: vertical; context_bar.spacing: 4; context_bar.homogeneous: false; header_box.spacing: 12; app_name_box.spacing: 0; formfactor_support_tile_wide.visible: false; formfactor_support_tile_narrow.visible: true; screenshots.compact: true; header_bar.show-title: false; link_list.dual-column: false; } } child: Adw.BreakpointBin breakpoint_bin { width-request: 360; height-request: 100; Adw.Breakpoint breakpoint { condition ("max-width: 525px") setters { top_box.margin-start: 10; top_box.margin-end: 10; bottom_box.margin-start: 10; bottom_box.margin-end: 10; bottom_box.margin-top: 5; wide_install_controls.visible: false; narrow_install_controls.visible: true; app_icon.valign: start; app_icon.pixel-size: 96; } } child: Overlay { [overlay] Box shadow_overlay { valign: start; height-request: 3; can-target: false; } child: ScrolledWindow main_scroll { child: Box main_box { orientation: vertical; vexpand: false; margin-bottom: 15; spacing: 20; Adw.Banner { title: _("This is a local preview, some details may differ from the published listing"); visible: bind $metainfo_banner_visible(template.ui-entry as <$BzResult>.object as <$BzFlatpakEntry>.remote-repo-name) as ; revealed: true; button-label: _("Preview Store Appearance"); button-clicked => $preview_other_metainfo_cb(template); } Adw.Clamp { maximum-size: 910; tightening-threshold: 576; margin-top: 15; child: Box top_box { orientation: vertical; margin-start: 25; margin-end: 25; spacing: 20; Box header_box { orientation: horizontal; spacing: 20; Image app_icon { valign: center; halign: center; pixel-size: 128; paintable: bind template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.icon-paintable; visible: bind $invert_boolean($is_null(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.icon-paintable) as ) as ; styles [ "icon-dropshadow", ] } Image fallback_icon { valign: center; halign: center; pixel-size: 128; icon-name: "application-x-executable"; visible: bind $is_null(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.icon-paintable) as ; styles [ "icon-dropshadow", ] } Box not_icon { orientation: horizontal; baseline-position: center; halign: fill; hexpand: true; spacing: 15; Box app_name_box { orientation: vertical; valign: center; hexpand: true; spacing: 3; Label { styles [ "title-1", "app-title", ] xalign: 0.0; wrap: true; lines: 2; ellipsize: end; wrap-mode: word_char; natural-wrap-mode: word; selectable: true; label: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.title; } Box { styles [ "bz-debug", ] halign: start; orientation: horizontal; spacing: 6; visible: bind template.state as <$BzStateInfo>.debug-mode; Button { icon-name: "edit-copy-symbolic"; clicked => $copy_id_cb(template); } Label { styles [ "bz-monospace", ] selectable: true; label: bind template.entry-group as <$BzEntryGroup>.id; } Button { label: "Inspect UI Entry"; clicked => $debug_id_inspect_cb(template); } } $BzDeveloperBadge { entry: bind template.ui-entry as <$BzResult>.object as <$BzEntry>; } Box { layout-manager: Adw.WrapLayout { child-spacing: 10; line-spacing: 0; }; Button { visible: bind $invert_boolean($is_null(template.ui-entry as <$BzResult>.object as <$BzEntry>.donation-url) as ) as ; styles [ "small-pill", "suggested-action", "support", ] margin-top: 8; valign: start; halign: start; tooltip-text: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.donation-url; clicked => $support_cb(template); child: Adw.ButtonContent { use-underline: true; label: _("_Support"); icon-name: "heart-filled-symbolic"; }; } $BzFavoriteButton { state: bind template.state as <$BzStateInfo>; entry: bind template.ui-entry as <$BzResult>.object as <$BzEntry>; } } } $BzInstallControls wide_install_controls { wide: true; entry-group: bind template.entry-group as <$BzEntryGroup>; state: bind template.state as <$BzStateInfo>; settings: bind template.state as <$BzStateInfo>.settings; update => $update_cb(template); } } } Box context_bar { hexpand: false; homogeneous: true; spacing: 0; orientation: horizontal; halign: fill; styles [ "app-context-bar", ] Box { homogeneous: true; Stack size_tile_stack { visible-child-name: bind $get_size_tile_child_name(template.entry-group as <$BzEntryGroup>.removable) as ; transition-type: crossfade; StackPage { name: "download"; child: $BzContextTile download_size_tile { label: bind try {$get_download_size_label( template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzFlatpakEntry>.runtime as <$BzResult>.object as <$BzEntry>.installed, template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzFlatpakEntry>.runtime as <$BzResult>.object as <$BzEntry>.size, ) as , _("Download")}; tooltip-text: bind $format_download_size_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>.size) as ; lozenge-style: "grey"; clicked => $size_cb(template); lozenge-child: Label { label: bind $format_size(template.ui-entry as <$BzResult>.object as <$BzEntry>.size) as ; use-markup: true; }; }; } StackPage { name: "installed"; child: $BzContextTile installed_size_tile { label: _("Installed"); tooltip-text: bind $format_installed_size_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>.installed-size) as ; lozenge-style: "grey"; clicked => $size_cb(template); lozenge-child: Label { label: bind $format_size(template.ui-entry as <$BzResult>.object as <$BzEntry>.installed-size) as ; use-markup: true; }; }; } } $BzContextTile license_tile { label: bind $get_license_label(template.ui-entry as <$BzResult>.object as <$BzEntry>) as ; lozenge-style: bind $bool_to_string(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-floss, "grey", "warning") as ; clicked => $license_cb(template); tooltip-text: bind $format_license_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>) as ; lozenge-child: Box { spacing: 6; Image { icon-name: bind $get_license_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-floss, 0) as ; } Image { icon-name: bind $get_license_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-floss, 1) as ; } }; } $BzContextTile { clicked => $safety_cb(template); label: bind $get_safety_rating_label(template.ui-entry as <$BzResult>.object as <$BzEntry>) as ; lozenge-style: bind $get_safety_rating_style(template.ui-entry as <$BzResult>.object as <$BzEntry>) as ; lozenge-child: Box { spacing: 4; Image { icon-name: bind $get_safety_rating_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>,0) as ; visible: bind $invert_boolean($is_empty_string($get_safety_rating_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>,0) as ) as ) as ; } Image { icon-name: bind $get_safety_rating_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>,1) as ; visible: bind $invert_boolean($is_empty_string($get_safety_rating_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>,1) as ) as ) as ; } Image { icon-name: bind $get_safety_rating_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>,2) as ; visible: bind $invert_boolean($is_empty_string($get_safety_rating_icon(template.ui-entry as <$BzResult>.object as <$BzEntry>,2) as ) as ) as ; } }; } } Box { homogeneous: true; $BzContextTile formfactor_support_tile_wide { label: bind $get_formfactor_label(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly) as ; tooltip-text: bind $get_formfactor_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly) as ; clicked => $formfactor_cb(template); lozenge-style: "grey"; lozenge-child: Box { Image { visible: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly as ; icon-name: "device-support-adaptive-symbolic"; pixel-size: 56; styles [ "wide-image", ] } Image { visible: bind $invert_boolean(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly) as ; icon-name: "device-support-desktop-symbolic"; } }; } $BzContextTile formfactor_support_tile_narrow { label: bind $get_formfactor_label(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly) as ; tooltip-text: bind $get_formfactor_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly) as ; clicked => $formfactor_cb(template); lozenge-style: bind $bool_to_string(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly, "grey", "error") as ; visible: false; lozenge-child: Box { Image { visible: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly as ; icon-name: "device-support-adaptive-symbolic"; pixel-size: 56; styles [ "wide-image", ] } Image { visible: bind $invert_boolean(template.ui-entry as <$BzResult>.object as <$BzEntry>.is-mobile-friendly) as ; icon-name: "device-support-desktop-symbolic"; } }; } $BzContextTile { clicked => $age_rating_cb(template); tooltip-text: bind $get_age_rating_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>.content-rating) as ; label: bind $get_age_rating_label(template.ui-entry as <$BzResult>.object as <$BzEntry>.content-rating) as ; lozenge-style: bind $get_age_rating_style(template.ui-entry as <$BzResult>.object as <$BzEntry>.content-rating) as ; lozenge-child: Label { label: bind $format_age_rating(template.ui-entry as <$BzResult>.object as <$BzEntry>.content-rating) as ; hexpand: true; }; } $BzContextTile { can-target: bind $invert_boolean($is_null(template.ui-entry) as ) as ; sensitive: bind $invert_boolean($is_null(template.ui-entry as <$BzResult>.object as <$BzEntry>.recent-downloads) as ) as ; clicked => $dl_stats_cb(template); label: _("Downloads/Month"); tooltip-text: bind $format_recent_downloads_tooltip(template.ui-entry as <$BzResult>.object as <$BzEntry>.recent-downloads) as ; lozenge-style: "grey"; lozenge-child: Label { justify: center; label: bind $format_recent_downloads(template.ui-entry as <$BzResult>.object as <$BzEntry>.recent-downloads) as ; halign: center; use-markup: true; }; } } $BzInstallControls narrow_install_controls { wide: false; visible: false; margin-top: 6; entry-group: bind template.entry-group as <$BzEntryGroup>; state: bind template.state as <$BzStateInfo>; settings: bind template.state as <$BzStateInfo>.settings; update => $update_cb(template); } } Box { visible: bind $invert_boolean($is_null(template.entry-group as <$BzEntryGroup>.eol) as ) as ; orientation: vertical; spacing: 8; styles [ "card", "colored", "warning", ] Label { label: _("Stopped Receiving Core Updates"); margin-top: 8; margin-start: 8; margin-end: 8; wrap: true; wrap-mode: word_char; justify: center; styles [ "title-4", ] } Label { label: _("This app uses a runtime that no longer receives updates or security fixes. It may become unsafe to use."); margin-bottom: 8; margin-start: 8; margin-end: 8; wrap: true; wrap-mode: word_char; justify: center; } } }; } $BzScreenshotsCarousel screenshots { vexpand: true; hexpand: true; light-accent-color: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.light-accent-color; dark-accent-color: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.dark-accent-color; model: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.screenshot-paintables; captions: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.screenshot-captions; } Adw.Clamp { maximum-size: 910; tightening-threshold: 576; child: Box { orientation: vertical; Box bottom_box { orientation: vertical; valign: start; margin-start: 25; margin-end: 25; margin-bottom: 20; margin-top: 10; spacing: 15; Revealer { transition-type: slide_down; reveal-child: bind $logical_and( $logical_and($invert_boolean($is_zero(template.entry-group as <$BzEntryGroup>.user-data-size) as ) as ,$is_zero(template.entry-group as <$BzEntryGroup>.removable) as ) as , $invert_boolean($is_zero(template.entry-group as <$BzEntryGroup>.installable-and-available) as ) as ) as ; visible: bind $invert_boolean($logical_and($is_zero(template.entry-group as <$BzEntryGroup>.removable) as , $is_zero(template.entry-group as <$BzEntryGroup>.installable) as ) as ) as ; child: Box { height-request: 50; margin-bottom: 10; spacing: 12; styles [ "card", "colored", "accent", ] Label { halign: start; valign: center; xalign: 0; hexpand: true; margin-start: 12; margin-top: 12; margin-bottom: 12; label: bind $format_leftover_label(template.ui-entry as <$BzResult>.object as <$BzEntry>.title, template.entry-group as <$BzEntryGroup>.user-data-size) as ; use-markup: true; wrap: true; wrap-mode: word_char; justify: left; } Button { valign: center; margin-end: 8; clicked => $delete_user_data_cb(template); child: Adw.ButtonContent { icon-name: "user-trash-symbolic"; label: _("Trash Data"); }; } }; } Box { spacing: 10; orientation: vertical; Label { styles [ "title-2", ] valign: start; xalign: 0; wrap: true; wrap-mode: word_char; selectable: true; label: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.description; } $BzFadingClamp fading_clamp { max-height: bind $get_description_max_height(description_toggle.active) as ; min-max-height: 170; child: $BzAppstreamDescriptionRender { appstream-description: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.long-description; }; } } ToggleButton description_toggle { styles [ "circular", ] visible: bind fading_clamp.will-change; halign: center; child: Label { label: bind $get_description_toggle_text(description_toggle.active) as ; margin-start: 16; margin-end: 16; }; } $BzReleasesPreview releases_list { version-history: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.version-history; installed-versions: bind template.entry-group as <$BzEntryGroup>.installed-versions; } Revealer other_sources_revealer{ transition-type: swing_up; visible: bind $logical_or(other_sources_revealer.child-revealed as , other_sources_revealer.reveal-child as ) as ; reveal-child: bind $logical_and( $logical_and( $is_le(template.entry-group as <$BzEntryGroup>.removable, 0) as , $is_gt(template.entry-group as <$BzEntryGroup>.installable, 1) as ) as , $not(wide_install_controls.in-progress) as ) as ; child: Box { orientation: vertical; Label { halign: start; label: _("Other Sources"); margin-top: 5; margin-bottom: 8; margin-start: 3; visible: bind other_sources.visible; styles [ "heading", ] } $BzOtherSourcesList other_sources { entry-group: bind template.entry-group as <$BzEntryGroup>; download => $other_source_download_cb(template); } }; } Box { orientation: vertical; spacing: bind $choose_int(addons_more_btn.visible, 15, 3) as ; Box { orientation: vertical; visible: bind $invert_boolean($is_zero(addon_model.n-items) as ) as ; Label { styles ["heading"] halign: start; label: _("Add-ons"); margin-top: 5; margin-start: 3; } ListView { styles [ "navigation-sidebar", "installed-list-view", "full-view-addons" ] overflow: visible; model: NoSelection addon_model { model: bind $get_addon_groups(template.entry-group); }; factory: BuilderListItemFactory { template ListItem { activatable: false; selectable: false; focusable: false; child: $BzAddonTile { group: bind template.item as <$BzEntryGroup>; activated => $addon_tile_activated_cb(); }; } }; } Adw.PreferencesGroup addons_more_btn { visible: bind $should_show_addon_overflow(template.entry-group); Adw.ButtonRow { title: _("More Add-Ons"); end-icon-name: "go-next-symbolic"; activated => $install_addons_cb(template); } } } Box { orientation: vertical; Label { halign: start; label: _("Links"); margin-top: 5; margin-bottom: 8; margin-start: 3; visible: bind $logical_and( $invert_boolean($is_empty(template.ui-entry as <$BzResult>.object as <$BzEntry>.share-urls) as ) as , $logical_or($invert_boolean($is_zero(addon_model.n-items) as ) as , other_sources_revealer.reveal-child as ) as ) as ; styles [ "heading", ] } $BzShareList link_list { urls: bind template.ui-entry as <$BzResult>.object as <$BzEntry>.share-urls; dual-column: true; } } } Box { orientation: vertical; visible: bind $invert_boolean($is_zero(similar_apps_model.n-items) as ) as ; Label { styles [ "heading", "h4", ] label: _("Similar Apps"); xalign: 0; wrap: true; wrap-mode: word_char; margin-top: 5; margin-bottom: 8; margin-start: 3; } $BzDynamicListView { hexpand: true; scroll: false; noscroll-kind: flow-box; child-type: "BzAppTile"; child-prop: "group"; max-children-per-line: 3; model: SliceListModel similar_apps_model { offset: 0; size: 6; model: bind $get_developer_apps_entries(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.similar-apps, template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>) as ; }; } } Box { orientation: vertical; visible: bind $invert_boolean($is_zero(other_apps_model.n-items) as ) as ; Label { styles [ "heading", "h4", ] label: bind $format_other_apps_label(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.developer) as ; xalign: 0; wrap: true; wrap-mode: word_char; margin-top: 5; margin-bottom: 8; margin-start: 3; } $BzDynamicListView { hexpand: true; scroll: false; noscroll-kind: flow-box; child-type: "BzAppTile"; child-prop: "group"; max-children-per-line: 3; model: SliceListModel other_apps_model { offset: 0; size: 6; model: bind $get_developer_apps_entries(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.developer-apps, template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>) as ; }; } Button { visible: bind $is_longer(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.developer-apps, 6) as ; clicked => $more_apps_button_clicked_cb(template); halign: center; margin-top: 15; margin-bottom: 8; child: Label { label: bind $format_more_other_apps_label(template.entry-group as <$BzEntryGroup>.ui-entry as <$BzResult>.object as <$BzEntry>.developer) as ; justify: center; wrap: true; wrap-mode: word_char; }; styles [ "pill", ] } } } }; } }; }; }; }; }; } }; }; }