Skip to content

Commit

Permalink
Fade in (#35)
Browse files Browse the repository at this point in the history
* padawan - settimeout to keep container alive while user is on page

* padawan - deploy script

* fade-in - fade in child component rendered by Layout, don't render loading bar in menu, add scss for striped loading text

* fade-in - lazy load dialog wrapper, not modals wrapped by it - remove colors prop from charts, pass lighter/more consistent colors - add animation fade in via opacity to layout so ssr pages fade in - lazy load emojis and sentry to cut down on bundle size - add bundle analysis tool + script
  • Loading branch information
dcordz authored Jun 13, 2024
1 parent e77ba6c commit 62d4401
Show file tree
Hide file tree
Showing 35 changed files with 1,759 additions and 391 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.3.1
3.3.2
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

source 'https://rubygems.org'

ruby '3.3.1'
ruby '3.3.2'

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem 'rails', '~> 7.1.3', '>= 7.1.3.2'
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ DEPENDENCIES
webauthn

RUBY VERSION
ruby 3.3.1p55
ruby 3.3.2p78

BUNDLED WITH
2.5.9
39 changes: 39 additions & 0 deletions app/assets/stylesheets/scss/striped.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// https://lea.verou.me/demos/css3-patterns.html
// https://stackoverflow.com/questions/14072142/striped-text-in-css

@import "./_constants.scss";

$primary: map-get($sway-theme-colors, "primary");

.stripes {
height: 250px;
width: 375px;
float: left;
margin: 10px;
-webkit-background-size: 50px 50px;
-moz-background-size: 50px 50px;
background-size: 50px 50px;
-moz-box-shadow: 1px 1px 8px gray;
-webkit-box-shadow: 1px 1px 8px gray;
box-shadow: 1px 1px 8px gray;

.horizontal {
background-image: -webkit-gradient(
linear,
0 0,
0 100%,
color-stop(0.5, rgba(255, 255, 255, 0.2)),
color-stop(0.5, transparent),
to(transparent)
);
background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent);
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent);
background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent);
background-image: -o-linear-gradient(rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent);
background-image: linear-gradient(rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent);
}

.loading {
background-color: $primary;
}
}
41 changes: 6 additions & 35 deletions app/frontend/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,21 @@ import React, { PropsWithChildren } from "react";
// Load react-select
// @ts-expect-error - unused Select, importing here to have styles available
import Select from "react-select"; // eslint-disable-line
import { Animate } from "react-simple-animate";

interface IProps extends PropsWithChildren {
[key: string]: any;
}

const _Layout: React.FC<IProps> = ({ children, ...props }) => (
<AppDrawer>
{React.Children.map(children, (child) =>
React.isValidElement(child) ? React.cloneElement(child, { ...child?.props, ...props }) : child,
)}
{React.Children.map(children, (child) => (
<Animate play={true} start={{ opacity: 0 }} end={{ opacity: 1 }}>
{React.isValidElement(child) ? React.cloneElement(child, { ...child?.props, ...props }) : child}
</Animate>
))}

<Footer />

{/* <div className="min-h-full">
<nav className="bg-white shadow-sm">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-16">
<div className="flex">
<div className="hidden sm:-my-px sm:ml-6 sm:flex sm:space-x-8">
<InertiaLink
href="/"
className="border-transparent text-gray-900 inline-flex items-center px-1 pt-1 border-b-2 text-sm font-medium"
aria-current="page"
>
Home
</InertiaLink>
</div>
</div>
</div>
</div>
</nav>
<div className="py-10">
<main>
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div className="px-4 py-8 sm:px-0">
<div className="bg-white rounded-lg h-96 p-3">
{children}
</div>
</div>
</div>
</main>
</div>
</div> */}
</AppDrawer>
);

Expand Down
17 changes: 7 additions & 10 deletions app/frontend/components/bill/BillComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ import { router } from "@inertiajs/react";
import SwayLogo from "app/frontend/components/SwayLogo";
import SwaySpinner from "app/frontend/components/SwaySpinner";
import BillArguments from "app/frontend/components/bill/BillArguments";
import SuspenseFullScreen from "app/frontend/components/dialogs/SuspenseFullScreen";
import BillSummaryModal from "app/frontend/components/bill/BillSummaryModal";
import VoteButtonsContainer from "app/frontend/components/uservote/VoteButtonsContainer";
import { useLocale, useLocaleName } from "app/frontend/hooks/useLocales";
import { useUser } from "app/frontend/hooks/users/useUser";
import { formatDate } from "app/frontend/sway_utils/datetimes";
import { Animate } from "react-simple-animate";
import { sway } from "sway";

const BillSummaryModal = lazy(() => import("app/frontend/components/bill/BillSummaryModal"));
const BillMobileChartsContainer = lazy(() => import("app/frontend/components/bill/charts/BillMobileChartsContainer"));
const ShareButtons = lazy(() => import("app/frontend/components/social/ShareButtons"));
const BillActionLinks = lazy(() => import("app/frontend/components/bill/BillActionLinks"));
Expand Down Expand Up @@ -176,14 +175,12 @@ const BillComponent: React.FC<IProps> = ({ bill, sponsor, positions, userVote })
</div>
</div>

<SuspenseFullScreen>
<BillSummaryModal
summary={bill.summary}
organizationPosition={DEFAULT_ORGANIZATION_POSITION}
selectedOrganization={showSummary}
setSelectedOrganization={setShowSummary}
/>
</SuspenseFullScreen>
<BillSummaryModal
summary={bill.summary}
organizationPosition={DEFAULT_ORGANIZATION_POSITION}
selectedOrganization={showSummary}
setSelectedOrganization={setShowSummary}
/>
</div>
</div>
)}
Expand Down
6 changes: 5 additions & 1 deletion app/frontend/components/bill/BillCreatorSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ const BillCreatorSummary = forwardRef(({ field }: IProps, ref: React.Ref<string>
const [summary, setSummary] = useState<string>(formikField.value || "");

const handleSetSummary = useCallback(async (_fieldname: string, string: string) => {
setSummary(withEmojis(string));
withEmojis(string)
.then((emojis) => {
setSummary(emojis);
})
.catch(console.error);
}, []);

useEffect(() => {
Expand Down
39 changes: 21 additions & 18 deletions app/frontend/components/bill/BillSummaryModal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { titleize } from "app/frontend/sway_utils";

import { useCallback, useMemo } from "react";
import { lazy, useCallback, useMemo } from "react";
import { sway } from "sway";

import ButtonUnstyled from "app/frontend/components/ButtonUnstyled";
import SuspenseFullScreen from "app/frontend/components/dialogs/SuspenseFullScreen";
import OrganizationIcon from "app/frontend/components/organizations/OrganizationIcon";
import DialogWrapper from "../dialogs/DialogWrapper";
import BillSummaryMarkdown from "./BillSummaryMarkdown";
import ButtonUnstyled from "app/frontend/components/ButtonUnstyled";
const DialogWrapper = lazy(() => import("../dialogs/DialogWrapper"));

interface IProps {
summary: string;
Expand Down Expand Up @@ -61,23 +62,25 @@ const BillSummaryModal: React.FC<IProps> = ({
<>
<div className={`my-2 px-1 brighter-item-hover ${isOpen ? "d-none" : ""}`}>{renderSummary(true)}</div>
{isOpen && (
<DialogWrapper
open={true}
size="xl"
fullscreen
setOpen={() => setSelectedOrganization(undefined)}
style={{ margin: 0 }}
>
<div>
<SuspenseFullScreen>
<DialogWrapper
open={true}
size="xl"
fullscreen
setOpen={() => setSelectedOrganization(undefined)}
style={{ margin: 0 }}
>
<div>
<OrganizationIcon organization={organization} maxWidth={100} />
{organization?.name.toLowerCase() !== "sway" && (
<p className="bold">{titleize(organization?.name as string)}</p>
)}
<div>
<OrganizationIcon organization={organization} maxWidth={100} />
{organization?.name.toLowerCase() !== "sway" && (
<p className="bold">{titleize(organization?.name as string)}</p>
)}
</div>
{summary && renderSummary(false)}
</div>
{summary && renderSummary(false)}
</div>
</DialogWrapper>
</DialogWrapper>
</SuspenseFullScreen>
)}
</>
);
Expand Down
24 changes: 14 additions & 10 deletions app/frontend/components/bill/charts/BillChartsContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
/** @format */

import { isCongressLocale, isEmptyObject, logDev } from "app/frontend/sway_utils";
import { useRef, useState } from "react";
import { lazy, useRef, useState } from "react";
import { sway } from "sway";
import { useOpenCloseElement } from "../../../hooks/elements/useOpenCloseElement";
import { isEmptyScore } from "../../../sway_utils/charts";
import DialogWrapper from "../../dialogs/DialogWrapper";
import { BillChartFilters } from "./constants";
import DistrictVotesChart from "./DistrictVotesChart";
import TotalVotesChart from "./TotalVotesChart";
import { useAxiosGet } from "app/frontend/hooks/useAxios";
import FullScreenLoading from "app/frontend/components/dialogs/FullScreenLoading";
import { Button } from "react-bootstrap";
import SuspenseFullScreen from "app/frontend/components/dialogs/SuspenseFullScreen";

const DialogWrapper = lazy(() => import("../../dialogs/DialogWrapper"));

interface IProps {
bill: sway.IBill;
Expand Down Expand Up @@ -134,14 +136,16 @@ const BillChartsContainer: React.FC<IProps> = ({ bill, locale, filter }) => {
);
})}
{selectedChart && (
<DialogWrapper open={open} setOpen={handleClose}>
<selectedChart.Component
score={billScore}
bill={bill}
isEmptyScore={isEmptyScore(billScore)}
district={selectedChart.props.district as sway.IDistrict}
/>
</DialogWrapper>
<SuspenseFullScreen>
<DialogWrapper open={open} setOpen={handleClose}>
<selectedChart.Component
score={billScore}
bill={bill}
isEmptyScore={isEmptyScore(billScore)}
district={selectedChart.props.district as sway.IDistrict}
/>
</DialogWrapper>
</SuspenseFullScreen>
)}
</div>
);
Expand Down
23 changes: 13 additions & 10 deletions app/frontend/components/bill/charts/BillMobileChartsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

import { useLocale } from "app/frontend/hooks/useLocales";
import { SWAY_COLORS, isCongressLocale, titleize } from "app/frontend/sway_utils";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { lazy, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { FiBarChart, FiBarChart2, FiFlag, FiMap } from "react-icons/fi";
import { sway } from "sway";
import { useOpenCloseElement } from "../../../hooks/elements/useOpenCloseElement";

import { isEmptyScore } from "../../../sway_utils/charts";
import DialogWrapper from "../../dialogs/DialogWrapper";
import DistrictVotesChart from "./DistrictVotesChart";
import TotalVotes from "./TotalVotesChart";

import { useAxiosGet } from "app/frontend/hooks/useAxios";
import { Button } from "react-bootstrap";
import { BillChartFilters } from "./constants";
import SuspenseFullScreen from "app/frontend/components/dialogs/SuspenseFullScreen";
const DialogWrapper = lazy(() => import("../../dialogs/DialogWrapper"));

interface IProps {
bill: sway.IBill;
Expand Down Expand Up @@ -205,14 +206,16 @@ const BillMobileChartsContainer: React.FC<IProps> = ({ bill, filter }) => {
})}
</div>
{selectedChart && (
<DialogWrapper open={open} setOpen={handleClose}>
<selectedChart.Component
bill={bill}
score={billScore}
isEmptyScore={isEmptyScore(billScore)}
district={selectedChart.props.district as sway.IDistrict}
/>
</DialogWrapper>
<SuspenseFullScreen>
<DialogWrapper open={open} setOpen={handleClose}>
<selectedChart.Component
bill={bill}
score={billScore}
isEmptyScore={isEmptyScore(billScore)}
district={selectedChart.props.district as sway.IDistrict}
/>
</DialogWrapper>
</SuspenseFullScreen>
)}
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions app/frontend/components/bill/charts/DistrictVotesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ const DistrictVotesChart: React.FC<IChildChartProps> = ({ bill, score, district
datasets: [
{
label: `Votes Cast in District ${district.number} on ${bill.title}`,
backgroundColor: district.number ? SWAY_COLORS.primaryLight : SWAY_COLORS.primary,
borderColor: SWAY_COLORS.primary,
backgroundColor: SWAY_COLORS.primarySubtle,
borderColor: SWAY_COLORS.primarySubtle,
borderWidth: 1,
hoverBackgroundColor: district.number ? SWAY_COLORS.primaryLight : SWAY_COLORS.primary,
hoverBackgroundColor: SWAY_COLORS.primary,
hoverBorderColor: SWAY_COLORS.primary,
barPercentage: 0.8,
categoryPercentage: 0.8,
Expand Down
6 changes: 3 additions & 3 deletions app/frontend/components/bill/charts/TotalVotesChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ const TotalVotesChart: React.FC<IChildChartProps> = ({ bill, score }) => {
datasets: [
{
label: `All Votes Cast in ${location} on ${bill.title}`,
backgroundColor: isCongressLocale(locale) ? SWAY_COLORS.primaryLight : SWAY_COLORS.primary,
borderColor: SWAY_COLORS.primary,
backgroundColor: SWAY_COLORS.primarySubtle,
borderColor: SWAY_COLORS.primarySubtle,
borderWidth: 1,
hoverBackgroundColor: isCongressLocale(locale) ? SWAY_COLORS.primaryLight : SWAY_COLORS.primary,
hoverBackgroundColor: SWAY_COLORS.primary,
hoverBorderColor: SWAY_COLORS.primary,
barPercentage: 0.8,
categoryPercentage: 0.8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ const BillCreatorOrganization: React.FC<IProps> = ({ swayFieldName, organization

const [summary, setSummary] = useState<string>(formikField?.value?.summary ?? "");
const handleChangeSummary = useCallback(async (_fieldname: string, fieldvalue: string) => {
setSummary(withEmojis(fieldvalue));
withEmojis(fieldvalue)
.then((emojis) => {
setSummary(emojis);
})
.catch(console.error);
}, []);

// Async updating of formik field using a useEffect and local summary state
Expand Down
Loading

0 comments on commit 62d4401

Please sign in to comment.