diff options
author | Sebastian <sebasjm@gmail.com> | 2021-07-09 23:15:49 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2021-07-09 23:15:53 -0300 |
commit | d29499b80a992a0d107327c0dfbf31bb2d2ba6f7 (patch) | |
tree | 256d181c9f3c3795841c71ef6400f4dce6a738f4 /packages | |
parent | 5881d957caf3bd7d3311cae7420ceb1e3fa5a9e1 (diff) |
migration css to linaria
Diffstat (limited to 'packages')
10 files changed, 273 insertions, 98 deletions
diff --git a/packages/taler-wallet-webextension/.gitignore b/packages/taler-wallet-webextension/.gitignore index 27d7e9786..0974a77aa 100644 --- a/packages/taler-wallet-webextension/.gitignore +++ b/packages/taler-wallet-webextension/.gitignore @@ -1,2 +1,3 @@ extension/ /storybook-static/ +/.linaria-cache/ diff --git a/packages/taler-wallet-webextension/.storybook/.babelrc b/packages/taler-wallet-webextension/.storybook/.babelrc index 39829d509..4476798e2 100644 --- a/packages/taler-wallet-webextension/.storybook/.babelrc +++ b/packages/taler-wallet-webextension/.storybook/.babelrc @@ -21,6 +21,6 @@ { //FIXME: check if we can remove this preset and just use default storybook presets "presets": [ - "preact-cli/babel" + "preact-cli/babel", ] }
\ No newline at end of file diff --git a/packages/taler-wallet-webextension/.storybook/main.js b/packages/taler-wallet-webextension/.storybook/main.js index 38ca14b64..cd58d4d1d 100644 --- a/packages/taler-wallet-webextension/.storybook/main.js +++ b/packages/taler-wallet-webextension/.storybook/main.js @@ -40,8 +40,9 @@ module.exports = { '@babel/preset-react', { runtime: 'automatic', }, - 'preset-react-jsx-transform' + 'preset-react-jsx-transform' ], + "@linaria", ], }), webpackFinal: (config) => { @@ -51,6 +52,30 @@ module.exports = { react: "preact/compat", "react-dom": "preact/compat", }; + + // we need to add @linaria loader AFTER the babel-loader + // https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack + config.module.rules[0] = { + ...(config.module.rules[0]), + loader: undefined, // Disable the predefined babel-loader on the rule + use: [ + { + ...(config.module.rules[0].use[0]), + loader: 'babel-loader', + }, + { + loader: '@linaria/webpack-loader', + options: { + sourceMap: true, //always true since this is dev + babelOptions: { + presets: config.module.rules[0].use[0].options.presets, + } + // Pass the current babel options to linaria's babel instance + } + } + ] + }; + return config; }, } diff --git a/packages/taler-wallet-webextension/package.json b/packages/taler-wallet-webextension/package.json index 1c6795234..a5908af25 100644 --- a/packages/taler-wallet-webextension/package.json +++ b/packages/taler-wallet-webextension/package.json @@ -27,6 +27,15 @@ "@babel/core": "^7.14.0", "@babel/plugin-transform-react-jsx-source": "^7.12.13", "@babel/preset-typescript": "^7.13.0", + + "@linaria/babel-preset": "^3.0.0-beta.4", + "@linaria/core": "^3.0.0-beta.4", + "@linaria/react": "^3.0.0-beta.7", + "@linaria/rollup": "^3.0.0-beta.7", + "@linaria/shaker": "^3.0.0-beta.7", + "@linaria/webpack-loader": "^3.0.0-beta.7", + "@rollup/plugin-alias": "^3.1.2", + "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-image": "^2.0.6", "@rollup/plugin-json": "^4.1.0", @@ -41,6 +50,7 @@ "@types/jest": "^26.0.23", "@types/node": "^14.14.22", "ava": "3.15.0", + "babel-loader": "^8.2.2", "babel-plugin-transform-react-jsx": "^6.24.1", "enzyme": "^3.11.0", "enzyme-adapter-preact-pure": "^3.1.0", @@ -51,6 +61,7 @@ "preact-render-to-string": "^5.1.19", "rimraf": "^3.0.2", "rollup": "^2.37.1", + "rollup-plugin-css-only": "^3.1.0", "rollup-plugin-ignore": "^1.0.9", "rollup-plugin-sourcemaps": "^0.6.3", "rollup-plugin-terser": "^7.0.2", diff --git a/packages/taler-wallet-webextension/rollup.config.js b/packages/taler-wallet-webextension/rollup.config.js index 80b4f6eec..7e7ec0032 100644 --- a/packages/taler-wallet-webextension/rollup.config.js +++ b/packages/taler-wallet-webextension/rollup.config.js @@ -6,8 +6,18 @@ import builtins from "builtin-modules"; import replace from "@rollup/plugin-replace"; import ignore from "rollup-plugin-ignore" import image from '@rollup/plugin-image'; +import linaria from '@linaria/rollup'; +import css from 'rollup-plugin-css-only'; +import alias from '@rollup/plugin-alias'; const makePlugins = () => [ + alias({ + entries: [ + { find: 'react', replacement: 'preact/compat' }, + { find: 'react-dom', replacement: 'preact/compat' } + ] + }), + ignore(["module", "os"]), nodeResolve({ browser: true, @@ -31,6 +41,14 @@ const makePlugins = () => [ json(), image(), + + linaria({ + sourceMap: process.env.NODE_ENV !== 'production', + }), + css({ + output: 'styles.css', + }), + ]; diff --git a/packages/taler-wallet-webextension/src/components/styled/index.tsx b/packages/taler-wallet-webextension/src/components/styled/index.tsx new file mode 100644 index 000000000..6e7e736a5 --- /dev/null +++ b/packages/taler-wallet-webextension/src/components/styled/index.tsx @@ -0,0 +1,135 @@ +// import { FunctionalComponent, JSX } from 'preact'; +// import styled from './preact-styled' + +// import { css } from '@linaria/core'; +import { styled } from '@linaria/react'; + +export const PopupBox = styled.div` + height: calc(320px - 34px - 16px); + display: flex; + flex-direction: column; + + & > section { + overflow: auto; + } + + & > footer { + padding-top: 5px; + flex-direction: row; + justify-content: flex-end; + display: flex; + & > button { + margin-left: 5px; + } + } +` + +const Button = styled.button` + display: inline-block; + zoom: 1; + line-height: normal; + white-space: nowrap; + vertical-align: middle; + text-align: center; + cursor: pointer; + user-select: none; + box-sizing: border-box; + + font-family: inherit; + font-size: 100%; + padding: 0.5em 1em; + color: #444; /* rgba not supported (IE 8) */ + color: rgba(0, 0, 0, 0.8); /* rgba supported */ + border: 1px solid #999; /*IE 6/7/8*/ + border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/ + background-color: '#e6e6e6'; + text-decoration: none; + border-radius: 2px; + + :focus { + outline: 0; + } + + [disabled] { + border: none; + background-image: none; + /* csslint ignore:start */ + filter: alpha(opacity=40); + /* csslint ignore:end */ + opacity: 0.4; + cursor: not-allowed; + box-shadow: none; + pointer-events: none; + } + + :hover { + filter: alpha(opacity=90); + background-image: linear-gradient( + transparent, + rgba(0, 0, 0, 0.05) 40%, + rgba(0, 0, 0, 0.1) + ); + } +`; + +const ButtonVariant = styled(Button)` + color: white; + border-radius: 4px; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); +` + +export const ButtonPrimary = styled(ButtonVariant)` + background-color: rgb(66, 184, 221); +` + +export const ButtonSuccess = styled(ButtonVariant)` + background-color: rgb(28, 184, 65); +` + +export const ButtonWarning = styled(ButtonVariant)` + background-color: rgb(223, 117, 20); +` + +export const ButtonDestructive = styled(ButtonVariant)` + background-color: rgb(202, 60, 60); +` + +export const BoldLight = styled.div` +color: gray; +font-weight: bold; +` +export const Centered = styled.div` + text-align: center; + & > :not(:first-child) { + margin-top: 15px; + } +` +export const Row = styled.div` + display: flex; + border: 1px solid gray; + border-radius: 0.5em; + margin: 0.5em 0; + justify-content: space-between; + padding: 0.5em; +` + +export const SmallText = styled.div` + font-size: small; + margin-top: 0.5em; +` + +export const SmallTextLight = styled(SmallText)` + color: gray; +` + +export const CenteredText = styled.div` + white-space: nowrap; + text-align: center; +` + +export const CenteredTextBold = styled(CenteredText)` + white-space: nowrap; + text-align: center; + font-weight: bold; + color: ${((props: any): any => String(props.color) as any) as any}; +` diff --git a/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx b/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx index 2d28a6ddc..ed03f2087 100644 --- a/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx +++ b/packages/taler-wallet-webextension/src/popup/Backup.stories.tsx @@ -62,7 +62,7 @@ export const LotOfProviders = createExample(TestedComponent, { "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - },{ + }, { "active": true, "syncProviderBaseUrl": "http://sync.taler:9967/", "lastSuccessfulBackupTimestamp": { @@ -82,43 +82,57 @@ export const LotOfProviders = createExample(TestedComponent, { "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - },{ + }, { "active": false, "syncProviderBaseUrl": "http://sync.demo.taler.net/", "paymentProposalIds": [], "paymentStatus": { - "type": ProviderPaymentType.Unpaid, + "type": ProviderPaymentType.Pending, }, "terms": { "annualFee": "KUDOS:0.1", "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - },{ + }, { "active": false, "syncProviderBaseUrl": "http://sync.demo.taler.net/", "paymentProposalIds": [], "paymentStatus": { - "type": ProviderPaymentType.Unpaid, + "type": ProviderPaymentType.InsufficientBalance, }, "terms": { "annualFee": "KUDOS:0.1", "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - },{ + }, { "active": false, "syncProviderBaseUrl": "http://sync.demo.taler.net/", "paymentProposalIds": [], "paymentStatus": { - "type": ProviderPaymentType.Unpaid, + "type": ProviderPaymentType.TermsChanged, + newTerms: { + annualFee: 'USD:2', + storageLimitInMegabytes: 8, + supportedProtocolVersion: '2', + }, + oldTerms: { + annualFee: 'USD:1', + storageLimitInMegabytes: 16, + supportedProtocolVersion: '1', + + }, + paidUntil: { + t_ms: 'never' + } }, "terms": { "annualFee": "KUDOS:0.1", "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - },{ + }, { "active": false, "syncProviderBaseUrl": "http://sync.demo.taler.net/", "paymentProposalIds": [], @@ -130,7 +144,7 @@ export const LotOfProviders = createExample(TestedComponent, { "storageLimitInMegabytes": 16, "supportedProtocolVersion": "0.0" } - },{ + }, { "active": false, "syncProviderBaseUrl": "http://sync.demo.taler.net/", "paymentProposalIds": [], diff --git a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx index d7a2d863c..6e60acc74 100644 --- a/packages/taler-wallet-webextension/src/popup/BackupPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/BackupPage.tsx @@ -16,9 +16,14 @@ import { i18n, Timestamp } from "@gnu-taler/taler-util"; -import { ProviderInfo } from "@gnu-taler/taler-wallet-core"; +import { ProviderInfo, ProviderPaymentStatus } from "@gnu-taler/taler-wallet-core"; import { differenceInMonths, formatDuration, intervalToDuration } from "date-fns"; -import { Fragment, JSX, VNode } from "preact"; +import { FunctionalComponent, Fragment, JSX, VNode, AnyComponent } from "preact"; +import { + BoldLight, ButtonPrimary, ButtonSuccess, Centered, + CenteredText, CenteredTextBold, PopupBox, Row, + SmallText, SmallTextLight +} from "../components/styled"; import { useBackupStatus } from "../hooks/useBackupStatus"; import { Pages } from "./popup"; @@ -31,7 +36,7 @@ export function BackupPage({ onAddProvider }: Props): VNode { if (!status) { return <div>Loading...</div> } - return <BackupView providers={status.providers} onAddProvider={onAddProvider} onSyncAll={status.sync}/>; + return <BackupView providers={status.providers} onAddProvider={onAddProvider} onSyncAll={status.sync} />; } export interface ViewProps { @@ -42,44 +47,35 @@ export interface ViewProps { export function BackupView({ providers, onAddProvider, onSyncAll }: ViewProps): VNode { return ( - <div style={{ height: 'calc(320px - 34px - 16px)', overflow: 'auto' }}> - <div style={{ display: 'flex', flexDirection: 'column' }}> - <section style={{ flex: '1 0 auto', height: 'calc(320px - 34px - 34px - 16px)', overflow: 'auto' }}> - - {!!providers.length && <div> - {providers.map((provider) => { - return <BackupLayout - status={provider.paymentStatus} - timestamp={provider.lastSuccessfulBackupTimestamp} - id={provider.syncProviderBaseUrl} - active={provider.active} - title={provider.syncProviderBaseUrl} - /> - })} - </div>} - {!providers.length && <div style={{ color: 'gray', fontWeight: 'bold', marginTop: 80, textAlign: 'center' }}> - <div>No backup providers configured</div> - <button class="pure-button button-success" style={{ marginTop: 15 }} onClick={onAddProvider}><i18n.Translate>Add provider</i18n.Translate></button> - </div>} - - </section> - {!!providers.length && <footer style={{ marginTop: 'auto', display: 'flex', flexShrink: 0 }}> - <div style={{ width: '100%', flexDirection: 'row', justifyContent: 'flex-end', display: 'flex' }}> - <button class="pure-button button-secondary" style={{ marginLeft: 5 }} onClick={onSyncAll}>{ - providers.length > 1 ? - <i18n.Translate>Sync all backups</i18n.Translate> : - <i18n.Translate>Sync now</i18n.Translate> - }</button> - <button class="pure-button button-success" style={{ marginLeft: 5 }} onClick={onAddProvider}><i18n.Translate>Add provider</i18n.Translate></button> - </div> - </footer>} - </div> - </div> + <PopupBox style={{ justifyContent: !providers.length ? 'center' : 'space-between' }}> + <section> + {providers.map((provider) => <BackupLayout + status={provider.paymentStatus} + timestamp={provider.lastSuccessfulBackupTimestamp} + id={provider.syncProviderBaseUrl} + active={provider.active} + title={provider.syncProviderBaseUrl} + /> + )} + {!providers.length && <Centered> + <BoldLight>No backup providers configured</BoldLight> + <ButtonSuccess onClick={onAddProvider}><i18n.Translate>Add provider</i18n.Translate></ButtonSuccess> + </Centered>} + </section> + {!!providers.length && <footer> + <ButtonPrimary onClick={onSyncAll}>{ + providers.length > 1 ? + <i18n.Translate>Sync all backups</i18n.Translate> : + <i18n.Translate>Sync now</i18n.Translate> + }</ButtonPrimary> + <ButtonSuccess onClick={onAddProvider}>Add provider</ButtonSuccess> + </footer>} + </PopupBox> ) } interface TransactionLayoutProps { - status: any; + status: ProviderPaymentStatus; timestamp?: Timestamp; title: string; id: string; @@ -92,55 +88,33 @@ function BackupLayout(props: TransactionLayoutProps): JSX.Element { dateStyle: "medium", timeStyle: "short", } as any); + + return ( - <div - style={{ - display: "flex", - flexDirection: "row", - border: "1px solid gray", - borderRadius: "0.5em", - margin: "0.5em 0", - justifyContent: "space-between", - padding: "0.5em", - }} - > - <div - style={{ display: "flex", flexDirection: "column", color: !props.active ? "gray" : undefined }} - > - <div style={{ }}> - <a href={Pages.provider_detail.replace(':pid', encodeURIComponent(props.id))}><span>{props.title}</span></a> - </div> - - {dateStr && <div style={{ fontSize: "small", marginTop: '0.5em' }}>Last synced: {dateStr}</div>} - {!dateStr && <div style={{ fontSize: "small", color: 'gray' }}>Not synced</div>} + <Row> + <div style={{ color: !props.active ? "grey" : undefined }}> + <a href={Pages.provider_detail.replace(':pid', encodeURIComponent(props.id))}><span>{props.title}</span></a> + + {dateStr && <SmallText>Last synced: {dateStr}</SmallText>} + {!dateStr && <SmallTextLight>Not synced</SmallTextLight>} </div> - <div style={{ - marginLeft: "auto", - display: "flex", - flexDirection: "column", - alignItems: "center", - alignSelf: "center" - }}> - <div style={{ display: 'flex', flexDirection: 'column' }}> - { - props.status?.type === 'paid' ? - <Fragment> - <div style={{ whiteSpace: 'nowrap', textAlign: 'center' }}> - Expires in - </div> - <div style={{ whiteSpace: 'nowrap', textAlign: 'center', fontWeight: 'bold', color: colorByTimeToExpire(props.status.paidUntil) }}> - {daysUntil(props.status.paidUntil)} - </div> - </Fragment> - : - 'unpaid' - } - </div> + <div> + {props.status?.type === 'paid' ? + <ExpirationText until={props.status.paidUntil} /> : + <div>{props.status.type}</div> + } </div> - </div> + </Row> ); } +function ExpirationText({ until }: { until: Timestamp }) { + return <Fragment> + <CenteredText> Expires in </CenteredText> + <CenteredTextBold {...({color:colorByTimeToExpire(until)})}> {daysUntil(until)} </CenteredTextBold> + </Fragment> +} + function colorByTimeToExpire(d: Timestamp) { if (d.t_ms === 'never') return 'rgb(28, 184, 65)' const months = differenceInMonths(d.t_ms, new Date()) diff --git a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx index b7a6f847c..0d48ab070 100644 --- a/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx +++ b/packages/taler-wallet-webextension/src/popup/ProviderDetailPage.tsx @@ -15,15 +15,11 @@ */ -import { BackupBackupProviderTerms, i18n, Timestamp } from "@gnu-taler/taler-util"; +import { i18n, Timestamp } from "@gnu-taler/taler-util"; import { ProviderInfo, ProviderPaymentStatus, ProviderPaymentType } from "@gnu-taler/taler-wallet-core"; -import { ContractTermsUtil } from "@gnu-taler/taler-wallet-core/src/util/contractTerms"; -import { formatDuration, intervalToDuration, format } from "date-fns"; +import { format, formatDuration, intervalToDuration } from "date-fns"; import { Fragment, VNode } from "preact"; -import { useRef, useState } from "preact/hooks"; -import { useBackupStatus } from "../hooks/useBackupStatus"; -import { useProviderStatus } from "../hooks/useProviderStatus.js"; -import * as wxApi from "../wxApi"; +import { useProviderStatus } from "../hooks/useProviderStatus"; interface Props { pid: string; diff --git a/packages/taler-wallet-webextension/static/popup.html b/packages/taler-wallet-webextension/static/popup.html index 9f6520a16..06e447924 100644 --- a/packages/taler-wallet-webextension/static/popup.html +++ b/packages/taler-wallet-webextension/static/popup.html @@ -4,6 +4,7 @@ <meta charset="utf-8" /> <link rel="stylesheet" type="text/css" href="/static/style/pure.css" /> <link rel="stylesheet" type="text/css" href="/static/style/popup.css" /> + <link rel="stylesheet" type="text/css" href="/dist/styles.css" /> <link rel="icon" href="/static/img/icon.png" /> <script src="/dist/popupEntryPoint.js"></script> </head> |