Merge pull request #1089 from basecamp/safari-optimization-time
Several performance optimizations
This commit is contained in:
@@ -92,29 +92,25 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card__background {
|
||||
.card:has(& img:not([src=""])) {
|
||||
.card__content,
|
||||
.card__meta,
|
||||
.workflow-stage:not(.workflow-stage--current) {
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
.card:has(.card__background img:not([src=""])) {
|
||||
.card__content,
|
||||
.card__meta,
|
||||
.workflow-stage:not(.workflow-stage--current) {
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease-in-out;
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.card:hover & {
|
||||
@media (any-hover: hover) {
|
||||
.card:hover & {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.card:hover & {
|
||||
img:not([src=""]) {
|
||||
filter: blur(3px) brightness(1.2);
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
@media (any-hover: hover) {
|
||||
.card:has(.card__background img:not([src=""])):hover .card__background img:not([src=""]) {
|
||||
filter: blur(3px) brightness(1.2);
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -308,11 +308,11 @@
|
||||
position: absolute;
|
||||
rotate: 5deg;
|
||||
transform-origin: top right;
|
||||
}
|
||||
|
||||
.card:has(&),
|
||||
.card-perma:has(&) {
|
||||
--card-color: var(--color-card-complete) !important;
|
||||
}
|
||||
.card:has(.card__closed),
|
||||
.card-perma:has(.card__closed) {
|
||||
--card-color: var(--color-card-complete) !important;
|
||||
}
|
||||
|
||||
.card__closed-title {
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
position: relative;
|
||||
view-transition-name: "filters";
|
||||
z-index: var(--z-popup);
|
||||
}
|
||||
|
||||
#header:has(&) {
|
||||
position: relative;
|
||||
z-index: var(--z-popup);
|
||||
}
|
||||
#header:has(.filters) {
|
||||
position: relative;
|
||||
z-index: var(--z-popup);
|
||||
}
|
||||
|
||||
.filters {
|
||||
|
||||
.btn {
|
||||
--btn-border-color: var(--color-ink-medium);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
"actions-start title actions-end";
|
||||
max-inline-size: 100dvw;
|
||||
padding: calc(var(--block-space-half) + env(safe-area-inset-top)) var(--main-padding);
|
||||
view-transition-name: header;
|
||||
|
||||
/* Change the grid size depending on how many buttons are present */
|
||||
&:has(.header__actions > *:nth-child(1)) { --header-button-count: 1; }
|
||||
|
||||
@@ -60,13 +60,11 @@
|
||||
cursor: pointer;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:focus-visible {
|
||||
.input--file:has(&) {
|
||||
outline: 0.15rem solid var(--color-selected-dark);
|
||||
}
|
||||
}
|
||||
&:has(input[type="file"]:focus),
|
||||
&:has(input[type="file"]:focus-visible) {
|
||||
outline: 0.15rem solid var(--color-selected-dark);
|
||||
}
|
||||
|
||||
&:is(.avatar) {
|
||||
|
||||
@@ -31,16 +31,16 @@
|
||||
--panel-padding: var(--block-space) var(--block-space) 0 var(--block-space);
|
||||
}
|
||||
|
||||
#header:has(&) {
|
||||
position: relative;
|
||||
z-index: var(--z-nav);
|
||||
}
|
||||
|
||||
.card & {
|
||||
inline-size: 260px;
|
||||
}
|
||||
}
|
||||
|
||||
#header:has(.popup) {
|
||||
position: relative;
|
||||
z-index: var(--z-nav);
|
||||
}
|
||||
|
||||
.popup__footer {
|
||||
background-color: var(--color-canvas);
|
||||
border-block-start: 1px solid var(--color-ink-lighter);
|
||||
|
||||
@@ -50,11 +50,12 @@
|
||||
margin-inline: auto;
|
||||
max-block-size: 32rem;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* Links should hug media contained within */
|
||||
a:has(&) {
|
||||
display: inline-block;
|
||||
}
|
||||
/* Links should hug media contained within */
|
||||
a:has(img),
|
||||
a:has(video) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Avoid extra space due to empty paragraphs */
|
||||
|
||||
@@ -8,7 +8,7 @@ class CardsController < ApplicationController
|
||||
|
||||
enable_collection_filtering only: :index
|
||||
|
||||
PAGE_SIZE = 50
|
||||
PAGE_SIZE = 25
|
||||
|
||||
def index
|
||||
@considering = page_and_filter_for @filter.with(engagement_status: "considering"), per_page: PAGE_SIZE
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class My::MenusController < ApplicationController
|
||||
include FilterScoped
|
||||
|
||||
def show
|
||||
fresh_when @user_filtering
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
module TimeHelper
|
||||
def local_datetime_tag(datetime, style: :time, **attributes)
|
||||
# Render empty space to ensure it takes height until the local time is loaded via JS
|
||||
tag.time " ".html_safe, **attributes, datetime: datetime.iso8601, data: { local_time_target: style, action: "turbo:morph-element->local-time#refreshTarget" }
|
||||
tag.time " ".html_safe, **attributes, datetime: datetime.to_i, data: { local_time_target: style, action: "turbo:morph-element->local-time#refreshTarget" }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
import { differenceInDays } from "helpers/date_helpers"
|
||||
import { differenceInDays, secondsToDate } from "helpers/date_helpers"
|
||||
|
||||
const DEFAULT_LOCALE = "en-US"
|
||||
|
||||
@@ -89,7 +89,7 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
#formatTime(formatter, target) {
|
||||
const dt = new Date(target.getAttribute("datetime"))
|
||||
const dt = secondsToDate(parseInt(target.getAttribute("datetime")))
|
||||
target.innerHTML = formatter.format(dt)
|
||||
target.title = this.datetimeFormatter.format(dt)
|
||||
}
|
||||
|
||||
@@ -9,3 +9,7 @@ export function signedDifferenceInDays(fromDate, toDate) {
|
||||
export function beginningOfDay(date) {
|
||||
return new Date(date.getFullYear(), date.getMonth(), date.getDate())
|
||||
}
|
||||
|
||||
export function secondsToDate(seconds) {
|
||||
return new Date(seconds * 1000)
|
||||
}
|
||||
|
||||
@@ -1,43 +1,13 @@
|
||||
<% cache user_filtering do %>
|
||||
<nav data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<%= render "filters/menu/button" %>
|
||||
<nav data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside">
|
||||
<%= render "filters/menu/button" %>
|
||||
|
||||
<%= tag.dialog class: "fizzy-menu filter popup popup--animated panel margin-block-start-half",
|
||||
data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter",
|
||||
controller: "filter navigable-list",
|
||||
dialog_target: "dialog",
|
||||
navigable_list_focus_on_selection_value: false,
|
||||
navigable_list_actionable_items_value: true } do %>
|
||||
<div class="flex gap">
|
||||
<%= text_field_tag :search, nil,
|
||||
type: "search",
|
||||
role: "combobox",
|
||||
placeholder: "Filter…",
|
||||
class: "input input--transparent txt-small",
|
||||
autofocus: true,
|
||||
autocorrect: "off",
|
||||
autocomplete: "off",
|
||||
aria: { activedescendant: "" },
|
||||
data: {
|
||||
"1p-ignore": "true",
|
||||
filter_target: "input",
|
||||
navigable_list_target: "input",
|
||||
action: "input->filter#filter" } %>
|
||||
<button class="fizzy-menu__close btn borderless txt-small" data-action="dialog#close">
|
||||
<%= icon_tag "close" %>
|
||||
<span class="for-screen-reader">Close menu</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<%= render "filters/menu/hotkeys" %>
|
||||
<%= render "filters/menu/custom", user_filtering: user_filtering %>
|
||||
<%= render "filters/menu/collections", user_filtering: user_filtering %>
|
||||
<%= render "filters/menu/tags", user_filtering: user_filtering %>
|
||||
<%= render "filters/menu/users", user_filtering: user_filtering %>
|
||||
<%= render "filters/menu/places", user_filtering: user_filtering %>
|
||||
|
||||
<%= render "filters/menu/shortcut_notice" %>
|
||||
<% end %>
|
||||
</nav>
|
||||
<% end %>
|
||||
<%= tag.dialog class: "fizzy-menu filter popup popup--animated panel margin-block-start-half",
|
||||
data: {
|
||||
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter",
|
||||
controller: "filter navigable-list",
|
||||
dialog_target: "dialog",
|
||||
navigable_list_focus_on_selection_value: false,
|
||||
navigable_list_actionable_items_value: true } do %>
|
||||
<%= turbo_frame_tag "my_menu", src: my_menu_path, target: "_top" %>
|
||||
<% end %>
|
||||
</nav>
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<%= turbo_frame_tag "my_menu", target: "_top" do %>
|
||||
<div class="flex gap">
|
||||
<%= text_field_tag :search, nil,
|
||||
type: "search",
|
||||
role: "combobox",
|
||||
placeholder: "Filter…",
|
||||
class: "input input--transparent txt-small",
|
||||
autofocus: true,
|
||||
autocorrect: "off",
|
||||
autocomplete: "off",
|
||||
aria: { activedescendant: "" },
|
||||
data: {
|
||||
"1p-ignore": "true",
|
||||
filter_target: "input",
|
||||
navigable_list_target: "input",
|
||||
action: "input->filter#filter" } %>
|
||||
<button class="fizzy-menu__close btn borderless txt-small" data-action="dialog#close">
|
||||
<%= icon_tag "close" %>
|
||||
<span class="for-screen-reader">Close menu</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<%= render "filters/menu/hotkeys" %>
|
||||
<%= render "filters/menu/custom", user_filtering: @user_filtering %>
|
||||
<%= render "filters/menu/collections", user_filtering: @user_filtering %>
|
||||
<%= render "filters/menu/tags", user_filtering: @user_filtering %>
|
||||
<%= render "filters/menu/users", user_filtering: @user_filtering %>
|
||||
<%= render "filters/menu/places", user_filtering: @user_filtering %>
|
||||
|
||||
<%= render "filters/menu/shortcut_notice" %>
|
||||
<% end %>
|
||||
@@ -124,6 +124,7 @@ Rails.application.routes.draw do
|
||||
namespace :my do
|
||||
resources :pins
|
||||
resource :timezone
|
||||
resource :menu
|
||||
end
|
||||
|
||||
namespace :prompts do
|
||||
|
||||
Reference in New Issue
Block a user