diff --git a/assets/css/application.scss b/assets/css/application.scss index 2f1f44d33..119c822fd 100644 --- a/assets/css/application.scss +++ b/assets/css/application.scss @@ -43,6 +43,7 @@ $fa-font-path: '~@fortawesome/fontawesome-free/webfonts'; @import "~views/admin"; @import "~views/burger"; @import "~views/communication"; +@import "~views/footer"; @import "~views/header"; @import "~views/markdown"; @import "~views/metabar"; diff --git a/assets/css/common/_measurements.scss b/assets/css/common/_measurements.scss index 56f6ea628..0bb571ea3 100644 --- a/assets/css/common/_measurements.scss +++ b/assets/css/common/_measurements.scss @@ -14,10 +14,12 @@ $font-family-monospace: "Droid Sans Mono", monospace; --block-header-height: 2rem; - --navbar-size: 40px; - --navbar-secondary-size: 36px; - --navbar-avatar-size: 36px; - --navbar-input-size: 32px; + --navbar-size: 4rem; + --navbar-secondary-size: 2.5rem; + --navbar-avatar-size: 2.5rem; + --navbar-input-size: 2rem; + --navbar-input-width: 18vw; + --navbar-input-max-width: 22rem; --button-group-height: 2rem; --button-group-tall-height: 2.5rem; diff --git a/assets/css/elements/_avatar.scss b/assets/css/elements/_avatar.scss index def386f12..178f04ee4 100644 --- a/assets/css/elements/_avatar.scss +++ b/assets/css/elements/_avatar.scss @@ -1,4 +1,6 @@ .avatar--navbar { width: var(--navbar-avatar-size); height: var(--navbar-avatar-size); + border-radius: 100%; + overflow: hidden; } diff --git a/assets/css/elements/_base.scss b/assets/css/elements/_base.scss index a7f624619..e64a9df63 100644 --- a/assets/css/elements/_base.scss +++ b/assets/css/elements/_base.scss @@ -12,6 +12,7 @@ body { main { padding: var(--padding-normal); + flex-grow: 1; } @include if-mobile { diff --git a/assets/css/elements/_block.scss b/assets/css/elements/_block.scss index 4231357de..98ee8be85 100644 --- a/assets/css/elements/_block.scss +++ b/assets/css/elements/_block.scss @@ -102,6 +102,7 @@ .block--fixed { padding: var(--padding-normal); + border-radius: var(--border-radius-inner); } .block__tab { diff --git a/assets/css/elements/_flash.scss b/assets/css/elements/_flash.scss index 14f327d5d..14562c37a 100644 --- a/assets/css/elements/_flash.scss +++ b/assets/css/elements/_flash.scss @@ -1,13 +1,8 @@ @mixin flash-type($type) { .flash--#{$type} { border: 1px solid var(--#{$type}-border-color); - box-shadow: 0 -1px var(--#{$type}-dark-color) inset; background: var(--#{$type}-color); - .flash__icon { - border-right: 1px solid var(--#{$type}-dark-color); - } - .flash__message { border-left: 1px solid var(--#{$type}-border-color); } @@ -27,6 +22,7 @@ grid-template-columns: auto 1fr; margin: var(--padding-normal); margin-bottom: 0; + border-radius: var(--border-radius-inner); } @include if-phone { diff --git a/assets/css/views/_footer.scss b/assets/css/views/_footer.scss new file mode 100644 index 000000000..38c27953c --- /dev/null +++ b/assets/css/views/_footer.scss @@ -0,0 +1,14 @@ +footer { + display: flex; + flex-wrap: wrap; + gap: var(--padding-large); + padding: var(--padding-normal); + background: var(--primary-dark-color); + justify-content: center; +} + +footer > span { + order: 1; + width: 100%; + text-align: center; +} diff --git a/assets/css/views/_header.scss b/assets/css/views/_header.scss index 5fe730905..fb01d67d0 100644 --- a/assets/css/views/_header.scss +++ b/assets/css/views/_header.scss @@ -1,95 +1,105 @@ -.header { - background: var(--primary-color); +header { + display: flex; line-height: var(--navbar-size); padding: 0 var(--padding-normal); - border-bottom: 1px solid var(--primary-border-color); - box-shadow: 0 1px var(--primary-muted-color) inset, 0 -1px var(--primary-dark-color) inset; font-size: var(--font-header-size); + gap: var(--padding-large); + align-items: center; } -.header--secondary { - background: var(--secondary-dark-color); - border-color: var(--secondary-color); - line-height: var(--navbar-secondary-size); - - .header__link { - border-right-color: var(--secondary-color); - border-left-color: var(--secondary-dark-color); - - & > .fa { - margin-right: var(--padding-small); - } +.header__link { + color: var(--text-color) !important; +} - &:hover { - background: var(--secondary-muted-color); - } - } +.header__link--user { + display: flex; + align-items: center; + gap: var(--padding-normal); } -.header__spacer { - flex: 1 0 auto; - height: var(--navbar-size); +.header__logo { + font-size: var(--font-h1-size) } -.header__link { - color: var(--text-color) !important; - display: block; - position: relative; - flex-shrink: 0; - padding: 0 var(--padding-small); - border-right: 1px solid var(--primary-border-color); - border-left: 1px solid var(--primary-dark-color); - - &:hover { - background: var(--primary-dark-color); - } +.header__search { + @extend .flex; + @extend .flex--no-wrap; + @extend .flex--centered; + + border: 0; + border-radius: var(--border-radius-inner); + background: var(--primary-muted-color); + height: var(--navbar-input-size); } -.header__link--no-hover:hover { - background: 0 !important; +.header__search > button { + background: 0; + border: 0; } .header__input { @include animated-transition; height: var(--navbar-input-size); - background: var(--primary-muted-color); font-size: var(--font-size); + background: 0; border: 0; + box-shadow: 0; } -select.header__input { - cursor: pointer; +.header__input--text { + width: var(--navbar-input-width); + max-width: var(--navbar-input-max-width); } -select.header__input:hover { - @include animated-transition; - background: var(--primary-dark-color) !important; +.header__search__button { + display: flex; + align-items: center; + height: var(--navbar-input-size); + color: var(--text-color) !important; + padding: 0 var(--padding-normal); } -.header__search { - @extend .flex__row; - height: var(--navbar-size); - padding: 0 var(--padding-small); - border-right: 1px solid var(--primary-border-color); - border-left: 1px solid var(--primary-dark-color); +.header__search__button:hover { + background: var(--primary-color); + cursor: pointer; } -.header__buttons { - border: 0; - border-radius: 0; - border-left: 1px solid var(--primary-dark-color); +.header__filter-form { + padding: 0 var(--padding-normal); } -.header__search__button { - height: var(--navbar-input-size); +nav.header__secondary { + display: flex; + line-height: var(--navbar-secondary-size); + padding: 0 var(--padding-normal); + font-size: var(--font-header-size); + gap: var(--padding-large); + align-items: center; background: var(--primary-muted-color); - box-shadow: 0 -1px var(--secondary-dark-color) inset; } -.header__search__button:hover { - background: var(--primary-dark-color) !important; +nav.dropdown__content { + line-height: var(--navbar-secondary-size); } -.header__filter-form { - padding: 0 var(--padding-small); +@include if-mobile { + header { + gap: var(--padding-normal); + flex-wrap: wrap; + margin-bottom: var(--padding-normal); + } + + nav.header__secondary { + display: none; + } + + form.header__search { + width: 100%; + order: 1; + } + + .header__input--text { + width: 100% !important; + max-width: 100% !important; + } } diff --git a/lib/philomena_web/templates/layout/_footer.html.slime b/lib/philomena_web/templates/layout/_footer.html.slime index 72fb1d543..9a2068021 100644 --- a/lib/philomena_web/templates/layout/_footer.html.slime +++ b/lib/philomena_web/templates/layout/_footer.html.slime @@ -1,20 +1,18 @@ -footer#footer - #footer_content - - footer_data = footer_data() +footer + - footer_data = footer_data() - = for column <- footer_data["cols"] do - .footercol - h5 = column + = for column <- footer_data["cols"] do + .footercol + h5 = column - = for row <- footer_data[column] do - = if row["bold"] do - strong - a href=row["url"] target=row["target"]||"_self" = row["title"] - - else + = for row <- footer_data[column] do + = if row["bold"] do + strong a href=row["url"] target=row["target"]||"_self" = row["title"] - br - - #serving_info + - else + a href=row["url"] target=row["target"]||"_self" = row["title"] + br + span ' Powered by a> href="https://github.com/philomena-dev/philomena" philomena | ( diff --git a/lib/philomena_web/templates/layout/_header.html.slime b/lib/philomena_web/templates/layout/_header.html.slime index 36049ed5d..61c931d6c 100644 --- a/lib/philomena_web/templates/layout/_header.html.slime +++ b/lib/philomena_web/templates/layout/_header.html.slime @@ -1,162 +1,144 @@ -header.header - .flex.flex--centered.flex--start-bunched.flex--maybe-wrap - .flex.flex--centered - #js-burger-toggle.hidden--desktop - a.header__link href="#" - i.fa.fa-bars - a.header__link href="/" - i.fa.fw.favicon-home - span.fa__text.hidden--mobile - ' Derpibooru - a.header__link.hidden--mobile href="/images/new" title="Upload" - i.fa.fa-upload +header + #js-burger-toggle.hidden--desktop + a.header__link href="#" + i.fa.fa-bars + a.header__logo.header__link href="/" + i.fab.fa-phoenix-framework> + span.hidden--mobile Philomena + a.header__link.hidden--mobile href="/images/new" title="Upload" + i.fa.fa-upload + = form_for @conn, Routes.search_path(@conn, :index), [method: "get", class: "header__search", enforce_utf8: false], fn f -> + input.input.input--text.header__input.header__input--text#q name="q" title="For terms all required, separate with ',' or 'AND'; also supports 'OR' for optional terms and '-' or 'NOT' for negation. Search with a blank query for more options or click the ? for syntax help." value=@conn.params["q"] placeholder="Search" autocapitalize="none" - = form_for @conn, Routes.search_path(@conn, :index), [method: "get", class: "header__search flex flex--no-wrap flex--centered", enforce_utf8: false], fn f -> - input.input.input--text.header__input.header__input--search#q name="q" title="For terms all required, separate with ',' or 'AND'; also supports 'OR' for optional terms and '-' or 'NOT' for negation. Search with a blank query for more options or click the ? for syntax help." value=@conn.params["q"] placeholder="Search" autocapitalize="none" + = if present?(@conn.params["sf"]) do + input type="hidden" name="sf" value=@conn.params["sf"] + = if present?(@conn.params["sd"]) do + input type="hidden" name="sd" value=@conn.params["sd"] + = if present?(@conn.params["hidden"]) do + input type="hidden" name="hidden" value=@conn.params["hidden"] - = if present?(@conn.params["sf"]) do - input type="hidden" name="sf" value=@conn.params["sf"] - = if present?(@conn.params["sd"]) do - input type="hidden" name="sd" value=@conn.params["sd"] - = if present?(@conn.params["hidden"]) do - input type="hidden" name="hidden" value=@conn.params["hidden"] + = if hides_images?(@conn) do + = select f, :del, [{"-D", ""}, {"+D", 1}, {"*D", "deleted"}, {"DO", "only"}], name: "del", class: "input header__input js-staff-action", autocomplete: "off" - = if hides_images?(@conn) do - = select f, :del, [{"-D", ""}, {"+D", 1}, {"*D", "deleted"}, {"DO", "only"}], name: "del", class: "input header__input js-staff-action", autocomplete: "off" + button.header__search__button type="submit" title="Search" + i.fas.fa-search + a.header__search__button href="/search/reverse" title="Search using an image" + i.fa-search-button.fas.fa-camera + a.header__search__button href="/pages/search_syntax" title="Search syntax help" + i.fa-search-button.fas.fa-question + .flex__grow + = if @current_user do + a.header__link href="/notifications" title="Notifications" + i.fas.fa-bell> + /span.js-notification-ticker.fa__text.header__counter data-notification-count=@notification_count = @notification_count - button.header__search__button type="submit" title="Search" - i.fas.fa-search - a.header__search__button href="/search/reverse" title="Search using an image" - i.fa-search-button.fas.fa-camera - a.header__search__button href="/pages/search_syntax" title="Search syntax help" - i.fa-search-button.fas.fa-question - - .flex.flex--centered.flex--no-wrap.header__force-right - = if @current_user do - a.header__link href="/notifications" title="Notifications" - i.fas.fa-bell> - span.js-notification-ticker.fa__text.header__counter data-notification-count=@notification_count = @notification_count - - a.header__link href="/conversations" title="Conversations" - = if @conversation_count > 0 do - i.fa-unread-icon.fas.fa-envelope-open> - span.header__counter - = @conversation_count - - else - i.fas.fa-envelope> - span.header__counter.hidden - | 0 - - a.header__link href="/conversations" title="Conversations" - = if @conversation_count > 0 do - i.fa.fa-envelope> - span.fa-embedded__text.header__counter - = @conversation_count - - else - i.fa.fa-envelope> - span.fa-embedded__text.header__counter.hidden - | 0 - - a.header__link.hidden--mobile href="/filters" title="Filters" - i.fa.fa-filter - span.hidden--tablet< Filters - - = form_for @user_changeset, Routes.filter_current_path(@conn, :update), [class: "header__filter-form", id: "filter-quick-form"], fn f -> - = select f, :current_filter_id, @available_filters, name: "id", id: "filter-quick-menu", class: "input header__input", data: [change_submit: "#filter-quick-form"], autocomplete: "off" + a.header__link href="/conversations" title="Conversations" + = if @conversation_count > 0 do + i.fa-unread-icon.fas.fa-envelope-open> + span.header__counter + = @conversation_count + - else + i.fas.fa-envelope + a.header__link.hidden--mobile href="/filters" title="Filters" + i.fa.fa-filter + span.hidden--tablet< Filters - = form_for @user_changeset, Routes.filter_spoiler_type_path(@conn, :update), [class: "header__filter-form hidden--mobile", id: "spoiler-quick-form"], fn f -> - = select f, :spoiler_type, @spoiler_types, id: "spoiler-quick-menu", class: "input header__input", data: [change_submit: "#spoiler-quick-form"], autocomplete: "off" + .header__search + = form_for @user_changeset, Routes.filter_current_path(@conn, :update), [class: "header__filter-form", id: "filter-quick-form"], fn f -> + = select f, :current_filter_id, @available_filters, name: "id", id: "filter-quick-menu", class: "input header__input", data: [change_submit: "#filter-quick-form"], autocomplete: "off" - .dropdown.header__dropdown - a.header__link.header__link-user href=Routes.profile_path(@conn, :show, @current_user) - = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, class: "avatar--navbar" - span.header__link-user__dropdown-arrow.hidden--mobile data-click-preventdefault="true" - nav.dropdown__content.dropdown__content--right.hidden--mobile.js-burger-links - a href=Routes.profile_path(@conn, :show, @current_user) - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-user - .dropdown__text - = @current_user.name - hr.dropdown__separator - a href="/search?q=my:watched" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-eye - .dropdown__text Watched - a href="/search?q=my:faves" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-star - .dropdown__text Faves - a href="/search?q=my:upvotes" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-arrow-up - .dropdown__text Upvotes - a href=Routes.gallery_path(@conn, :index, gallery: [creator: @current_user.name]) - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-image - .dropdown__text Galleries - a href="/search?q=my:uploads" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-upload - .dropdown__text Uploads - a href="/comments?cq=my:comments" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-comments - .dropdown__text Comments - a href="/posts?pq=my:posts" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-pen-square - .dropdown__text Posts - a href=Routes.profile_artist_link_path(@conn, :index, @current_user) - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-link - .dropdown__text Links - a href="/conversations" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-envelope - .dropdown__text Messages - hr.dropdown__separator - a href="/settings/edit" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-cogs - .dropdown__text Settings - a href=Routes.registration_path(@conn, :edit) - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-user - .dropdown__text Account - hr.dropdown__separator - a href=Routes.session_path(@conn, :delete) data-method="delete" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-sign-out-alt - .dropdown__text Logout - - else - a.header__link.hidden--mobile href="/filters" - | Filters ( - = @current_filter.name - | ) - span.js-burger-links.hidden--mobile - a.header__link href="/settings/edit" - i.fa.fa-fw.fa-cogs.hidden--desktop> - | Settings - a.header__link href=Routes.registration_path(@conn, :new) - | Register - a.header__link href=Routes.session_path(@conn, :new) - | Login + .header__search + = form_for @user_changeset, Routes.filter_spoiler_type_path(@conn, :update), [class: "header__filter-form hidden--mobile", id: "spoiler-quick-form"], fn f -> + = select f, :spoiler_type, @spoiler_types, id: "spoiler-quick-menu", class: "input header__input", data: [change_submit: "#spoiler-quick-form"], autocomplete: "off" -nav.header.header--secondary - .flex.flex--row.flex--centered.flex--spaced-out.flex--wrap - = render PhilomenaWeb.LayoutView, "_header_navigation.html", assigns - = if !is_nil(@current_user) and @current_user.role != "user" do - = render PhilomenaWeb.LayoutView, "_header_staff_links.html", assigns + .dropdown + a.header__link.header__link--user href=Routes.profile_path(@conn, :show, @current_user) + = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @current_user}, class: "avatar--navbar" + i.fa.fa-chevron-down + nav.dropdown__content.dropdown__content--right.hidden--mobile.js-burger-links + a href=Routes.profile_path(@conn, :show, @current_user) + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-user + .dropdown__text + = @current_user.name + hr.dropdown__separator + a href="/search?q=my:watched" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-eye + .dropdown__text Watched + a href="/search?q=my:faves" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-star + .dropdown__text Faves + a href="/search?q=my:upvotes" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-arrow-up + .dropdown__text Upvotes + a href=Routes.gallery_path(@conn, :index, gallery: [creator: @current_user.name]) + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-image + .dropdown__text Galleries + a href="/search?q=my:uploads" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-upload + .dropdown__text Uploads + a href="/comments?cq=my:comments" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-comments + .dropdown__text Comments + a href="/posts?pq=my:posts" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-pen-square + .dropdown__text Posts + a href=Routes.profile_artist_link_path(@conn, :index, @current_user) + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-link + .dropdown__text Links + a href="/conversations" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-envelope + .dropdown__text Messages + hr.dropdown__separator + a href="/settings/edit" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-cogs + .dropdown__text Settings + a href=Routes.registration_path(@conn, :edit) + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-user + .dropdown__text Account + hr.dropdown__separator + a href=Routes.session_path(@conn, :delete) data-method="delete" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-sign-out-alt + .dropdown__text Logout + - else + a.header__link.hidden--mobile href="/filters" + | Filters ( + = @current_filter.name + | ) + span.js-burger-links.hidden--mobile + a.header__link href="/settings/edit" + i.fa.fa-fw.fa-cogs.hidden--desktop> + | Settings + a.header__link href=Routes.registration_path(@conn, :new) + | Register + a.header__link href=Routes.session_path(@conn, :new) + | Login +nav.header__secondary + = render PhilomenaWeb.LayoutView, "_header_navigation.html", assigns + = if !is_nil(@current_user) and @current_user.role != "user" do + /= render PhilomenaWeb.LayoutView, "_header_staff_links.html", assigns diff --git a/lib/philomena_web/templates/layout/_header_navigation.html.slime b/lib/philomena_web/templates/layout/_header_navigation.html.slime index 40cdf2556..715548f73 100644 --- a/lib/philomena_web/templates/layout/_header_navigation.html.slime +++ b/lib/philomena_web/templates/layout/_header_navigation.html.slime @@ -1,57 +1,56 @@ -.flex.flex--row.hidden--mobile - .dropdown.header__dropdown - a.header__link href="/images" - i.fa.fa-image - | Images - span data-click-preventdefault="true" - i.fa.fa-caret-down< - .dropdown__content - a href="/images/random" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-random - .dropdown__text Random - .dropdown.header__dropdown - a.header__link href="/activity" - i.fa.fa-bullhorn - | Activity - span data-click-preventdefault="true" - i.fa.fa-caret-down< - .dropdown__content - a href="/comments" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-comments - .dropdown__text Comments - .dropdown.header__dropdown - a.header__link href="/forums" - i.fa.fa-comments - | Forums - span data-click-preventdefault="true" - i.fa.fa-caret-down< - .dropdown__content - = for forum <- @conn.assigns.forums do - a.dropdown__link href=Routes.forum_path(@conn, :show, forum) - = forum.name +.dropdown.header__dropdown + a.header__link href="/images" + i.fa.fa-image> + | Images + span data-click-preventdefault="true" + i.fa.fa-caret-down< + nav.dropdown__content + a href="/images/random" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-random> + .dropdown__text Random +.dropdown.header__dropdown + a.header__link href="/activity" + i.fa.fa-bullhorn> + | Activity + span data-click-preventdefault="true" + i.fa.fa-caret-down< + nav.dropdown__content + a href="/comments" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-comments> + .dropdown__text Comments +.dropdown.header__dropdown + a.header__link href="/forums" + i.fa.fa-comments> + | Forums + span data-click-preventdefault="true" + i.fa.fa-caret-down< + nav.dropdown__content + = for forum <- @conn.assigns.forums do + a.dropdown__link href=Routes.forum_path(@conn, :show, forum) + = forum.name - hr.dropdown__separator - a href="/posts" - .dropdown__item - .dropdown__icon - i.fa.fa-fw.fa-search - .dropdown__text Post Search - a.header__link href="/tags" - i.fa.fa-tag - | Tags - a.header__link href="/channels" - i.fa.fa-stream - ' Live - span.header__counter - = @conn.assigns.live_channels + hr.dropdown__separator + a href="/posts" + .dropdown__item + .dropdown__icon + i.fa.fa-fw.fa-search> + .dropdown__text Post Search +a.header__link href="/tags" + i.fa.fa-tag> + | Tags +a.header__link href="/channels" + i.fa.fa-stream> + ' Live + span.header__counter + = @conn.assigns.live_channels - a.header__link href="/galleries" - i.fa.fa-images - | Galleries - a.header__link href="/commissions" - i.fa.fa-briefcase - | Commissions +a.header__link href="/galleries" + i.fa.fa-images> + | Galleries +a.header__link href="/commissions" + i.fa.fa-briefcase> + | Commissions