@lightsparkdev/lightspark-sdk 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.fossa.yml +6 -0
- package/.prettierrc +1 -0
- package/.turbo/turbo-build.log +19 -0
- package/.turbo/turbo-lint.log +3 -0
- package/CHANGELOG.md +49 -0
- package/LICENSE +201 -0
- package/README.md +137 -0
- package/dist/Withdrawal-17e1c8af.d.ts +1672 -0
- package/dist/Withdrawal-27a4d10d.d.ts +1672 -0
- package/dist/chunk-3VRI7CHE.js +5508 -0
- package/dist/chunk-AGEUDR2V.js +4498 -0
- package/dist/chunk-N27QHRE4.js +5508 -0
- package/dist/client-3bba3f64.d.ts +1302 -0
- package/dist/index.cjs +6633 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1177 -0
- package/dist/objects/index.cjs +5347 -0
- package/dist/objects/index.d.ts +3 -0
- package/dist/objects/index.js +88 -0
- package/examples/node-scripts/authHelpers.ts +20 -0
- package/examples/node-scripts/createInvoice.ts +64 -0
- package/examples/node-scripts/example.ts +288 -0
- package/examples/node-scripts/getAccountDashboard.ts +24 -0
- package/examples/node-scripts/getNodeChannels.ts +34 -0
- package/examples/node-scripts/internalAuthHelpers.ts +26 -0
- package/examples/node-scripts/internal_example.ts +296 -0
- package/examples/node-scripts/package-lock.json +887 -0
- package/examples/node-scripts/package.json +22 -0
- package/examples/node-scripts/prettyPrintJsonForDocs.ts +62 -0
- package/examples/node-scripts/tsconfig.json +27 -0
- package/examples/oauth-example/README.md +19 -0
- package/examples/oauth-example/package-lock.json +16071 -0
- package/examples/oauth-example/package.json +50 -0
- package/examples/oauth-example/public/favicon.ico +0 -0
- package/examples/oauth-example/public/index.html +43 -0
- package/examples/oauth-example/public/logo192.png +0 -0
- package/examples/oauth-example/public/logo512.png +0 -0
- package/examples/oauth-example/public/manifest.json +25 -0
- package/examples/oauth-example/public/robots.txt +3 -0
- package/examples/oauth-example/src/App.css +7 -0
- package/examples/oauth-example/src/App.test.tsx +12 -0
- package/examples/oauth-example/src/App.tsx +16 -0
- package/examples/oauth-example/src/auth/AuthContext.ts +8 -0
- package/examples/oauth-example/src/auth/AuthProvider.tsx +44 -0
- package/examples/oauth-example/src/auth/RequireAuth.tsx +19 -0
- package/examples/oauth-example/src/auth/oauthProvider.ts +35 -0
- package/examples/oauth-example/src/components/Button.tsx +39 -0
- package/examples/oauth-example/src/components/CurrencyAmount.tsx +117 -0
- package/examples/oauth-example/src/components/Dashboard.tsx +158 -0
- package/examples/oauth-example/src/components/Table.tsx +22 -0
- package/examples/oauth-example/src/hooks/useAccountInfo.tsx +31 -0
- package/examples/oauth-example/src/icons/BitcoinB.tsx +20 -0
- package/examples/oauth-example/src/icons/Icon.tsx +121 -0
- package/examples/oauth-example/src/icons/Satoshi.tsx +28 -0
- package/examples/oauth-example/src/index.css +13 -0
- package/examples/oauth-example/src/index.tsx +23 -0
- package/examples/oauth-example/src/lightsparkclient/LightsparkClientContext.ts +10 -0
- package/examples/oauth-example/src/lightsparkclient/LightsparkClientProvider.tsx +53 -0
- package/examples/oauth-example/src/logo.svg +1 -0
- package/examples/oauth-example/src/pages/DashboardPage.tsx +71 -0
- package/examples/oauth-example/src/pages/LoginPage.tsx +63 -0
- package/examples/oauth-example/src/react-app-env.d.ts +1 -0
- package/examples/oauth-example/src/reportWebVitals.ts +15 -0
- package/examples/oauth-example/src/routes/index.tsx +15 -0
- package/examples/oauth-example/src/setupTests.ts +5 -0
- package/examples/oauth-example/src/utils/currency.ts +483 -0
- package/examples/oauth-example/tsconfig.json +20 -0
- package/examples/streaming-wallet-extension/.fossa.yml +6 -0
- package/examples/streaming-wallet-extension/README.md +17 -0
- package/examples/streaming-wallet-extension/craco.config.js +58 -0
- package/examples/streaming-wallet-extension/package-lock.json +18260 -0
- package/examples/streaming-wallet-extension/package.json +77 -0
- package/examples/streaming-wallet-extension/public/index.html +24 -0
- package/examples/streaming-wallet-extension/public/lightspark_full.png +0 -0
- package/examples/streaming-wallet-extension/public/lightspark_icon_circle.png +0 -0
- package/examples/streaming-wallet-extension/public/manifest.json +43 -0
- package/examples/streaming-wallet-extension/public/robots.txt +3 -0
- package/examples/streaming-wallet-extension/src/App.css +53 -0
- package/examples/streaming-wallet-extension/src/App.tsx +425 -0
- package/examples/streaming-wallet-extension/src/auth/AccountStorage.ts +28 -0
- package/examples/streaming-wallet-extension/src/auth/DemoAccountProvider.ts +99 -0
- package/examples/streaming-wallet-extension/src/auth/StreamingDemoCredentials.ts +10 -0
- package/examples/streaming-wallet-extension/src/background/PaymentStrategy.ts +36 -0
- package/examples/streaming-wallet-extension/src/background/PlaybackRange.ts +31 -0
- package/examples/streaming-wallet-extension/src/background/StreamingInvoiceHolder.ts +33 -0
- package/examples/streaming-wallet-extension/src/background/TransactionObserver.ts +66 -0
- package/examples/streaming-wallet-extension/src/background/VideoPlaybackRanges.ts +38 -0
- package/examples/streaming-wallet-extension/src/background/VideoProgressCache.ts +87 -0
- package/examples/streaming-wallet-extension/src/background/background.ts +145 -0
- package/examples/streaming-wallet-extension/src/background/messageHandling.ts +185 -0
- package/examples/streaming-wallet-extension/src/common/datetimes.ts +28 -0
- package/examples/streaming-wallet-extension/src/common/settings.ts +12 -0
- package/examples/streaming-wallet-extension/src/common/storage.ts +8 -0
- package/examples/streaming-wallet-extension/src/common/streamingTabs.ts +27 -0
- package/examples/streaming-wallet-extension/src/common/types.tsx +23 -0
- package/examples/streaming-wallet-extension/src/components/CirclePlusIcon.tsx +19 -0
- package/examples/streaming-wallet-extension/src/components/CurrencyAmount.tsx +110 -0
- package/examples/streaming-wallet-extension/src/components/CurrencyAmountRaw.tsx +195 -0
- package/examples/streaming-wallet-extension/src/components/LeftArrow.tsx +21 -0
- package/examples/streaming-wallet-extension/src/components/Loading.tsx +151 -0
- package/examples/streaming-wallet-extension/src/components/StreamingTransactionChip.tsx +95 -0
- package/examples/streaming-wallet-extension/src/components/TransactionRow.tsx +93 -0
- package/examples/streaming-wallet-extension/src/contentscript/content.ts +123 -0
- package/examples/streaming-wallet-extension/src/contentscript/lightsparkDemoDom.tsx +113 -0
- package/examples/streaming-wallet-extension/src/contentscript/videoElementParsers.ts +92 -0
- package/examples/streaming-wallet-extension/src/index.css +16 -0
- package/examples/streaming-wallet-extension/src/index.tsx +11 -0
- package/examples/streaming-wallet-extension/src/lightsparkClientProvider.tsx +26 -0
- package/examples/streaming-wallet-extension/src/react-app-env.d.ts +1 -0
- package/examples/streaming-wallet-extension/src/types/Messages.ts +17 -0
- package/examples/streaming-wallet-extension/tsconfig.json +20 -0
- package/package.json +87 -0
- package/src/auth/AccountTokenAuthProvider.ts +37 -0
- package/src/auth/index.ts +3 -0
- package/src/client.ts +759 -0
- package/src/graphql/BitcoinFeeEstimate.ts +13 -0
- package/src/graphql/CreateApiToken.ts +22 -0
- package/src/graphql/CreateInvoice.ts +18 -0
- package/src/graphql/CreateNodeWalletAddress.ts +13 -0
- package/src/graphql/CurrentAccount.ts +13 -0
- package/src/graphql/DecodeInvoice.ts +16 -0
- package/src/graphql/DeleteApiToken.ts +13 -0
- package/src/graphql/FundNode.ts +18 -0
- package/src/graphql/LightningFeeEstimateForInvoice.ts +21 -0
- package/src/graphql/LightningFeeEstimateForNode.ts +21 -0
- package/src/graphql/MultiNodeDashboard.ts +118 -0
- package/src/graphql/PayInvoice.ts +29 -0
- package/src/graphql/RecoverNodeSigningKey.ts +15 -0
- package/src/graphql/RequestWithdrawal.ts +25 -0
- package/src/graphql/SendPayment.ts +29 -0
- package/src/graphql/SingleNodeDashboard.ts +116 -0
- package/src/graphql/TransactionSubscription.ts +16 -0
- package/src/graphql/TransactionsForNode.ts +42 -0
- package/src/index.ts +5 -0
- package/src/objects/Account.ts +1222 -0
- package/src/objects/AccountToApiTokensConnection.ts +50 -0
- package/src/objects/AccountToChannelsConnection.ts +35 -0
- package/src/objects/AccountToNodesConnection.ts +62 -0
- package/src/objects/AccountToPaymentRequestsConnection.ts +50 -0
- package/src/objects/AccountToTransactionsConnection.ts +112 -0
- package/src/objects/ApiToken.ts +80 -0
- package/src/objects/BitcoinNetwork.ts +19 -0
- package/src/objects/BlockchainBalance.ts +102 -0
- package/src/objects/Channel.ts +283 -0
- package/src/objects/ChannelClosingTransaction.ts +150 -0
- package/src/objects/ChannelFees.ts +34 -0
- package/src/objects/ChannelOpeningTransaction.ts +150 -0
- package/src/objects/ChannelStatus.ts +25 -0
- package/src/objects/ChannelToTransactionsConnection.ts +86 -0
- package/src/objects/CreateApiTokenInput.ts +22 -0
- package/src/objects/CreateApiTokenOutput.ts +41 -0
- package/src/objects/CreateInvoiceInput.ts +27 -0
- package/src/objects/CreateInvoiceOutput.ts +21 -0
- package/src/objects/CreateNodeWalletAddressInput.ts +15 -0
- package/src/objects/CreateNodeWalletAddressOutput.ts +27 -0
- package/src/objects/CurrencyAmount.ts +55 -0
- package/src/objects/CurrencyUnit.ts +25 -0
- package/src/objects/DeleteApiTokenInput.ts +13 -0
- package/src/objects/DeleteApiTokenOutput.ts +23 -0
- package/src/objects/Deposit.ts +144 -0
- package/src/objects/Entity.ts +868 -0
- package/src/objects/FeeEstimate.ts +39 -0
- package/src/objects/FundNodeInput.ts +16 -0
- package/src/objects/FundNodeOutput.ts +28 -0
- package/src/objects/GraphNode.ts +110 -0
- package/src/objects/Hop.ts +108 -0
- package/src/objects/HtlcAttemptFailureCode.ts +65 -0
- package/src/objects/IncomingPayment.ts +141 -0
- package/src/objects/IncomingPaymentAttempt.ts +96 -0
- package/src/objects/IncomingPaymentAttemptStatus.ts +20 -0
- package/src/objects/IncomingPaymentToAttemptsConnection.ts +39 -0
- package/src/objects/Invoice.ts +226 -0
- package/src/objects/InvoiceData.ts +185 -0
- package/src/objects/InvoiceType.ts +15 -0
- package/src/objects/LightningFeeEstimateForInvoiceInput.ts +28 -0
- package/src/objects/LightningFeeEstimateForNodeInput.ts +25 -0
- package/src/objects/LightningFeeEstimateOutput.ts +33 -0
- package/src/objects/LightningTransaction.ts +393 -0
- package/src/objects/LightsparkNode.ts +377 -0
- package/src/objects/LightsparkNodePurpose.ts +17 -0
- package/src/objects/LightsparkNodeStatus.ts +29 -0
- package/src/objects/LightsparkNodeToChannelsConnection.ts +50 -0
- package/src/objects/Node.ts +273 -0
- package/src/objects/NodeAddress.ts +29 -0
- package/src/objects/NodeAddressType.ts +18 -0
- package/src/objects/NodeToAddressesConnection.ts +39 -0
- package/src/objects/OnChainTransaction.ts +318 -0
- package/src/objects/OutgoingPayment.ts +319 -0
- package/src/objects/OutgoingPaymentAttempt.ts +164 -0
- package/src/objects/OutgoingPaymentAttemptStatus.ts +18 -0
- package/src/objects/OutgoingPaymentAttemptToHopsConnection.ts +37 -0
- package/src/objects/OutgoingPaymentToAttemptsConnection.ts +39 -0
- package/src/objects/PageInfo.ts +31 -0
- package/src/objects/PayInvoiceInput.ts +33 -0
- package/src/objects/PayInvoiceOutput.ts +22 -0
- package/src/objects/PaymentFailureReason.ts +29 -0
- package/src/objects/PaymentRequest.ts +231 -0
- package/src/objects/PaymentRequestData.ts +183 -0
- package/src/objects/PaymentRequestStatus.ts +15 -0
- package/src/objects/Permission.ts +39 -0
- package/src/objects/RequestWithdrawalInput.ts +35 -0
- package/src/objects/RequestWithdrawalOutput.ts +24 -0
- package/src/objects/RichText.ts +19 -0
- package/src/objects/RoutingTransaction.ts +150 -0
- package/src/objects/RoutingTransactionFailureReason.ts +17 -0
- package/src/objects/Secret.ts +23 -0
- package/src/objects/SendPaymentInput.ts +30 -0
- package/src/objects/SendPaymentOutput.ts +22 -0
- package/src/objects/Transaction.ts +609 -0
- package/src/objects/TransactionFailures.ts +23 -0
- package/src/objects/TransactionStatus.ts +23 -0
- package/src/objects/TransactionType.ts +31 -0
- package/src/objects/TransactionUpdate.ts +67 -0
- package/src/objects/WalletDashboard.ts +32 -0
- package/src/objects/WebhookEventType.ts +15 -0
- package/src/objects/Withdrawal.ts +144 -0
- package/src/objects/WithdrawalMode.ts +15 -0
- package/src/objects/WithdrawalRequest.ts +224 -0
- package/src/objects/WithdrawalRequestStatus.ts +17 -0
- package/src/objects/WithdrawalRequestToChannelClosingTransactionsConnection.ts +57 -0
- package/src/objects/WithdrawalRequestToChannelOpeningTransactionsConnection.ts +57 -0
- package/src/objects/index.ts +108 -0
- package/tsconfig.json +5 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
|
|
3
|
+
type LoadingProps = { size: number };
|
|
4
|
+
|
|
5
|
+
export const LoadingSpinner = (props: LoadingProps) => {
|
|
6
|
+
return (
|
|
7
|
+
<Rotate size={props.size}>
|
|
8
|
+
<LoadingSvg />
|
|
9
|
+
</Rotate>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Rotate = styled.div<LoadingProps>`
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
animation: rotate 1s linear infinite;
|
|
16
|
+
width: ${(props) => `${props.size}px`};
|
|
17
|
+
height: ${(props) => `${props.size}px`};
|
|
18
|
+
|
|
19
|
+
@keyframes rotate {
|
|
20
|
+
0% {
|
|
21
|
+
transform: rotate(0deg);
|
|
22
|
+
}
|
|
23
|
+
100% {
|
|
24
|
+
transform: rotate(360deg);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
const LoadingSvg = () => (
|
|
30
|
+
<svg
|
|
31
|
+
width="100%"
|
|
32
|
+
viewBox="0 0 12 12"
|
|
33
|
+
fill="none"
|
|
34
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
35
|
+
>
|
|
36
|
+
<g clipPath="url(#clip0_1200_7026)">
|
|
37
|
+
<circle cx="6" cy="6" r="5.25" stroke="#333333" strokeWidth="1.5" />
|
|
38
|
+
<path
|
|
39
|
+
d="M6 11.25C3.10051 11.25 0.75 8.89949 0.75 6C0.75 3.10051 3.10051 0.75 6 0.75"
|
|
40
|
+
stroke="black"
|
|
41
|
+
strokeWidth="1.5"
|
|
42
|
+
strokeLinecap="round"
|
|
43
|
+
/>
|
|
44
|
+
<mask
|
|
45
|
+
id="mask0_1200_7026"
|
|
46
|
+
style={{ maskType: "alpha" }}
|
|
47
|
+
maskUnits="userSpaceOnUse"
|
|
48
|
+
x="0"
|
|
49
|
+
y="0"
|
|
50
|
+
width="7"
|
|
51
|
+
height="12"
|
|
52
|
+
>
|
|
53
|
+
<path
|
|
54
|
+
d="M6 11.25C3.10051 11.25 0.75 8.89949 0.75 6C0.75 3.10051 3.10051 0.75 6 0.75"
|
|
55
|
+
stroke="black"
|
|
56
|
+
strokeWidth="1.5"
|
|
57
|
+
strokeLinecap="round"
|
|
58
|
+
/>
|
|
59
|
+
</mask>
|
|
60
|
+
<g mask="url(#mask0_1200_7026)">
|
|
61
|
+
<g filter="url(#filter0_f_1200_7026)">
|
|
62
|
+
<ellipse
|
|
63
|
+
cx="6.375"
|
|
64
|
+
cy="2.625"
|
|
65
|
+
rx="35.25"
|
|
66
|
+
ry="14.25"
|
|
67
|
+
fill="url(#paint0_radial_1200_7026)"
|
|
68
|
+
/>
|
|
69
|
+
</g>
|
|
70
|
+
<g filter="url(#filter1_f_1200_7026)">
|
|
71
|
+
<ellipse
|
|
72
|
+
cx="6.75"
|
|
73
|
+
cy="-5.25"
|
|
74
|
+
rx="23.625"
|
|
75
|
+
ry="19.125"
|
|
76
|
+
fill="url(#paint1_radial_1200_7026)"
|
|
77
|
+
/>
|
|
78
|
+
</g>
|
|
79
|
+
</g>
|
|
80
|
+
</g>
|
|
81
|
+
<defs>
|
|
82
|
+
<filter
|
|
83
|
+
id="filter0_f_1200_7026"
|
|
84
|
+
x="-33.375"
|
|
85
|
+
y="-16.125"
|
|
86
|
+
width="79.5"
|
|
87
|
+
height="37.5"
|
|
88
|
+
filterUnits="userSpaceOnUse"
|
|
89
|
+
colorInterpolationFilters="sRGB"
|
|
90
|
+
>
|
|
91
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
92
|
+
<feBlend
|
|
93
|
+
mode="normal"
|
|
94
|
+
in="SourceGraphic"
|
|
95
|
+
in2="BackgroundImageFix"
|
|
96
|
+
result="shape"
|
|
97
|
+
/>
|
|
98
|
+
<feGaussianBlur
|
|
99
|
+
stdDeviation="2.25"
|
|
100
|
+
result="effect1_foregroundBlur_1200_7026"
|
|
101
|
+
/>
|
|
102
|
+
</filter>
|
|
103
|
+
<filter
|
|
104
|
+
id="filter1_f_1200_7026"
|
|
105
|
+
x="-21.375"
|
|
106
|
+
y="-28.875"
|
|
107
|
+
width="56.25"
|
|
108
|
+
height="47.25"
|
|
109
|
+
filterUnits="userSpaceOnUse"
|
|
110
|
+
colorInterpolationFilters="sRGB"
|
|
111
|
+
>
|
|
112
|
+
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
|
113
|
+
<feBlend
|
|
114
|
+
mode="normal"
|
|
115
|
+
in="SourceGraphic"
|
|
116
|
+
in2="BackgroundImageFix"
|
|
117
|
+
result="shape"
|
|
118
|
+
/>
|
|
119
|
+
<feGaussianBlur
|
|
120
|
+
stdDeviation="2.25"
|
|
121
|
+
result="effect1_foregroundBlur_1200_7026"
|
|
122
|
+
/>
|
|
123
|
+
</filter>
|
|
124
|
+
<radialGradient
|
|
125
|
+
id="paint0_radial_1200_7026"
|
|
126
|
+
cx="0"
|
|
127
|
+
cy="0"
|
|
128
|
+
r="1"
|
|
129
|
+
gradientUnits="userSpaceOnUse"
|
|
130
|
+
gradientTransform="translate(6.44679 2.59598) rotate(161.271) scale(23.5 14.7413)"
|
|
131
|
+
>
|
|
132
|
+
<stop stopColor="#0066FF" />
|
|
133
|
+
<stop offset="1" stopColor="#0066FF" stopOpacity="0" />
|
|
134
|
+
</radialGradient>
|
|
135
|
+
<radialGradient
|
|
136
|
+
id="paint1_radial_1200_7026"
|
|
137
|
+
cx="0"
|
|
138
|
+
cy="0"
|
|
139
|
+
r="1"
|
|
140
|
+
gradientUnits="userSpaceOnUse"
|
|
141
|
+
gradientTransform="translate(6.79812 -5.28895) rotate(145.825) scale(18.0291 17.2834)"
|
|
142
|
+
>
|
|
143
|
+
<stop stopColor="#FFC700" />
|
|
144
|
+
<stop offset="1" stopColor="#BF09FF" stopOpacity="0" />
|
|
145
|
+
</radialGradient>
|
|
146
|
+
<clipPath id="clip0_1200_7026">
|
|
147
|
+
<rect width="12" height="12" fill="white" />
|
|
148
|
+
</clipPath>
|
|
149
|
+
</defs>
|
|
150
|
+
</svg>
|
|
151
|
+
);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import { CurrencyUnit, Transaction } from "@lightsparkdev/lightspark-sdk";
|
|
3
|
+
import CurrencyAmountRaw from "./CurrencyAmountRaw";
|
|
4
|
+
import { LoadingSpinner } from "./Loading";
|
|
5
|
+
|
|
6
|
+
const StreamingTransactionChip = (props: {
|
|
7
|
+
transactions: Transaction[];
|
|
8
|
+
streamingDuration: number;
|
|
9
|
+
isStreaming: boolean;
|
|
10
|
+
}) => {
|
|
11
|
+
const filteredTransactions = props.transactions.filter(
|
|
12
|
+
(t) => t.typename === "OutgoingPayment"
|
|
13
|
+
);
|
|
14
|
+
// TODO: Probably need a unit normalization here to ensure they're all sats.
|
|
15
|
+
const totalTransactionAmount = filteredTransactions.reduce(
|
|
16
|
+
(acc, t) => acc + t.amount.originalValue / 1000,
|
|
17
|
+
0
|
|
18
|
+
);
|
|
19
|
+
return (
|
|
20
|
+
<Wrapper>
|
|
21
|
+
<InnerColumn>
|
|
22
|
+
<TopTextRow>Demo wallet</TopTextRow>
|
|
23
|
+
<BottomTextRow>
|
|
24
|
+
{props.isStreaming ? (
|
|
25
|
+
<>
|
|
26
|
+
<LoadingSpinner size={12} />
|
|
27
|
+
<span style={{ marginInlineStart: "4px" }}>Streaming</span>
|
|
28
|
+
</>
|
|
29
|
+
) : (
|
|
30
|
+
`${filteredTransactions.length} transactions`
|
|
31
|
+
)}
|
|
32
|
+
</BottomTextRow>
|
|
33
|
+
</InnerColumn>
|
|
34
|
+
<InnerColumn style={{ alignItems: "flex-end" }}>
|
|
35
|
+
<TopTextRow>
|
|
36
|
+
<CurrencyAmountRaw
|
|
37
|
+
value={-totalTransactionAmount}
|
|
38
|
+
unit={CurrencyUnit.SATOSHI}
|
|
39
|
+
symbol
|
|
40
|
+
/>
|
|
41
|
+
</TopTextRow>
|
|
42
|
+
<BottomTextRow>
|
|
43
|
+
{secondsToDurationString(Math.round(props.streamingDuration))}
|
|
44
|
+
</BottomTextRow>
|
|
45
|
+
</InnerColumn>
|
|
46
|
+
</Wrapper>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const secondsToDurationString = (seconds: number) => {
|
|
51
|
+
const hours = Math.floor(seconds / 3600);
|
|
52
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
53
|
+
const secondsLeft = seconds % 60;
|
|
54
|
+
const hoursString = hours > 0 ? `${hours}h ` : "";
|
|
55
|
+
const minutesString = minutes > 0 ? `${minutes}m ` : "";
|
|
56
|
+
const secondsString = secondsLeft > 0 ? `${secondsLeft}s` : "";
|
|
57
|
+
return `${hoursString}${minutesString}${secondsString}`;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const Wrapper = styled.div`
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: row;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
padding: 18px;
|
|
66
|
+
border: 1.6px solid #f2f2f2;
|
|
67
|
+
border-radius: 12px;
|
|
68
|
+
margin-bottom: 32px;
|
|
69
|
+
margin-top: 16px;
|
|
70
|
+
`;
|
|
71
|
+
|
|
72
|
+
const InnerColumn = styled.div`
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-direction: column;
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
const TopTextRow = styled.span`
|
|
78
|
+
color: black;
|
|
79
|
+
font-size: 14px;
|
|
80
|
+
font-weight: 700;
|
|
81
|
+
margin-bottom: 6px;
|
|
82
|
+
`;
|
|
83
|
+
|
|
84
|
+
const BottomTextRow = styled.div`
|
|
85
|
+
color: #666666;
|
|
86
|
+
font-size: 14px;
|
|
87
|
+
font-weight: 500;
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: row;
|
|
90
|
+
align-items: center;
|
|
91
|
+
height: 16px;
|
|
92
|
+
justify-content: center;
|
|
93
|
+
`;
|
|
94
|
+
|
|
95
|
+
export default StreamingTransactionChip;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import styled from "@emotion/styled";
|
|
2
|
+
import {
|
|
3
|
+
ChannelClosingTransaction,
|
|
4
|
+
ChannelOpeningTransaction,
|
|
5
|
+
IncomingPayment,
|
|
6
|
+
OutgoingPayment,
|
|
7
|
+
RoutingTransaction,
|
|
8
|
+
Transaction,
|
|
9
|
+
Withdrawal,
|
|
10
|
+
} from "@lightsparkdev/lightspark-sdk";
|
|
11
|
+
import { Maybe } from "../common/types";
|
|
12
|
+
import CurrencyAmount from "./CurrencyAmount";
|
|
13
|
+
|
|
14
|
+
export const getTransactionType = (typename: string): string => {
|
|
15
|
+
switch (typename) {
|
|
16
|
+
case "Deposit":
|
|
17
|
+
return "L1 Deposit";
|
|
18
|
+
case "Withdrawal":
|
|
19
|
+
return "L1 Withdraw";
|
|
20
|
+
case "ChannelOpeningTransaction":
|
|
21
|
+
return "Channel Open";
|
|
22
|
+
case "ChannelClosingTransaction":
|
|
23
|
+
return "Channel Close";
|
|
24
|
+
case "RoutingTransaction":
|
|
25
|
+
return "Route";
|
|
26
|
+
case "OutgoingPayment":
|
|
27
|
+
return "Payment";
|
|
28
|
+
case "IncomingPayment":
|
|
29
|
+
return "Payment Request";
|
|
30
|
+
default:
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const getTransactionOtherNode = (transaction: Transaction): Maybe<string> => {
|
|
36
|
+
switch (transaction.typename) {
|
|
37
|
+
case "Withdrawal":
|
|
38
|
+
return (transaction as Withdrawal).originId;
|
|
39
|
+
case "ChannelOpeningTransaction":
|
|
40
|
+
return (transaction as ChannelOpeningTransaction).channelId;
|
|
41
|
+
case "ChannelClosingTransaction":
|
|
42
|
+
return (transaction as ChannelClosingTransaction).channelId;
|
|
43
|
+
case "OutgoingPayment":
|
|
44
|
+
return (transaction as OutgoingPayment).destinationId;
|
|
45
|
+
case "IncomingPayment":
|
|
46
|
+
return (transaction as IncomingPayment).originId;
|
|
47
|
+
case "RoutingTransaction":
|
|
48
|
+
return (transaction as RoutingTransaction).incomingChannelId;
|
|
49
|
+
default:
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const TransactionRow = (props: { transaction: Transaction }) => {
|
|
55
|
+
return (
|
|
56
|
+
<TransactionWrapper>
|
|
57
|
+
<div
|
|
58
|
+
style={{
|
|
59
|
+
display: "flex",
|
|
60
|
+
flexDirection: "column",
|
|
61
|
+
marginInlineStart: "8px",
|
|
62
|
+
flex: "1",
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<div style={{ fontSize: "14px", fontWeight: 500 }}>
|
|
66
|
+
{getTransactionOtherNode(props.transaction)}
|
|
67
|
+
</div>
|
|
68
|
+
<div style={{ fontSize: "10px", color: "#8C8C8C" }}>
|
|
69
|
+
{getTransactionType(props.transaction.typename)}
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div style={{ fontSize: "16px", fontWeight: "bold", color: "#17C27C" }}>
|
|
73
|
+
<CurrencyAmount
|
|
74
|
+
amount={props.transaction.amount}
|
|
75
|
+
displayUnit={props.transaction.amount.preferredCurrencyUnit}
|
|
76
|
+
shortNumber
|
|
77
|
+
shortUnit
|
|
78
|
+
symbol
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
</TransactionWrapper>
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const TransactionWrapper = styled.div`
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-direction: row;
|
|
88
|
+
align-items: center;
|
|
89
|
+
padding: 16px;
|
|
90
|
+
border-bottom: 1px solid #e8e8e8;
|
|
91
|
+
`;
|
|
92
|
+
|
|
93
|
+
export default TransactionRow;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { ENABLE_YOUTUBE_AND_TWITCH } from "../common/settings";
|
|
2
|
+
import { VideoPlaybackUpdateMessage } from "../types/Messages";
|
|
3
|
+
import {
|
|
4
|
+
updateTransactionRows,
|
|
5
|
+
updateWalletBalances,
|
|
6
|
+
} from "./lightsparkDemoDom";
|
|
7
|
+
import {
|
|
8
|
+
getDomDetailsForLighstparkDemo,
|
|
9
|
+
getDomDetailsForTwitch,
|
|
10
|
+
getDomDetailsForYoutube,
|
|
11
|
+
} from "./videoElementParsers";
|
|
12
|
+
|
|
13
|
+
let currentTrackingDetails: VideoPlaybackUpdateMessage | null = null;
|
|
14
|
+
let timeUpdateListener: (() => void) | null = null;
|
|
15
|
+
|
|
16
|
+
const messageReceived = (
|
|
17
|
+
msg: any,
|
|
18
|
+
sender: chrome.runtime.MessageSender,
|
|
19
|
+
sendResponse: (response: any) => void
|
|
20
|
+
) => {
|
|
21
|
+
console.log("[content.js]. Message received", msg);
|
|
22
|
+
if (msg.id === "is_video_playing") {
|
|
23
|
+
sendResponse(currentTrackingDetails?.isPlaying || false);
|
|
24
|
+
} else if (
|
|
25
|
+
msg.id === "new_transactions" ||
|
|
26
|
+
msg.id === "transactions_updated"
|
|
27
|
+
) {
|
|
28
|
+
updateTransactionRows(msg.transactions);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const startListeningToVideoEvents = (videoElement: HTMLVideoElement) => {
|
|
33
|
+
console.log(
|
|
34
|
+
`Beginning listener on: ${JSON.stringify(currentTrackingDetails)}`
|
|
35
|
+
);
|
|
36
|
+
if (timeUpdateListener) {
|
|
37
|
+
videoElement.removeEventListener("timeupdate", timeUpdateListener);
|
|
38
|
+
}
|
|
39
|
+
timeUpdateListener = () => {
|
|
40
|
+
console.log("Time update", videoElement.currentTime);
|
|
41
|
+
const prevProgress = currentTrackingDetails?.progress || 0;
|
|
42
|
+
currentTrackingDetails = {
|
|
43
|
+
...currentTrackingDetails!,
|
|
44
|
+
progress: videoElement.currentTime,
|
|
45
|
+
duration: videoElement.duration,
|
|
46
|
+
prevProgress: prevProgress,
|
|
47
|
+
};
|
|
48
|
+
// No time updates while seeking.
|
|
49
|
+
if (
|
|
50
|
+
videoElement.seeking ||
|
|
51
|
+
Math.abs(videoElement.currentTime - prevProgress) > 2
|
|
52
|
+
)
|
|
53
|
+
return;
|
|
54
|
+
chrome.runtime
|
|
55
|
+
.sendMessage({ id: "video_progress", ...currentTrackingDetails })
|
|
56
|
+
.then((response) => {
|
|
57
|
+
if (response.amountToPay > 0) {
|
|
58
|
+
console.log(`Paying ${response.amountToPay} msats!`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const playListener = () => {
|
|
63
|
+
console.log("Play event");
|
|
64
|
+
currentTrackingDetails = {
|
|
65
|
+
...currentTrackingDetails!,
|
|
66
|
+
isPlaying: true,
|
|
67
|
+
};
|
|
68
|
+
chrome.runtime.sendMessage({ id: "video_play", ...currentTrackingDetails });
|
|
69
|
+
};
|
|
70
|
+
const pauseListener = () => {
|
|
71
|
+
console.log("Pause event");
|
|
72
|
+
currentTrackingDetails = {
|
|
73
|
+
...currentTrackingDetails!,
|
|
74
|
+
isPlaying: false,
|
|
75
|
+
};
|
|
76
|
+
chrome.runtime.sendMessage({
|
|
77
|
+
id: "video_pause",
|
|
78
|
+
...currentTrackingDetails,
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
videoElement.addEventListener("timeupdate", timeUpdateListener);
|
|
82
|
+
videoElement.addEventListener("play", playListener);
|
|
83
|
+
videoElement.addEventListener("pause", pauseListener);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
chrome.runtime.onMessage.addListener(messageReceived);
|
|
87
|
+
|
|
88
|
+
const afterDOMLoaded = (numRetries: number) => {
|
|
89
|
+
console.log("[content.js]. DOM loaded");
|
|
90
|
+
const isLightsparkDemo =
|
|
91
|
+
window.location.host.includes("lightspark") ||
|
|
92
|
+
window.location.host.includes("localhost") ||
|
|
93
|
+
window.location.host.includes("sparkinfra.net");
|
|
94
|
+
const parseResponse =
|
|
95
|
+
window.location.host.includes("youtube") && ENABLE_YOUTUBE_AND_TWITCH
|
|
96
|
+
? getDomDetailsForYoutube()
|
|
97
|
+
: window.location.host.includes("twitch") && ENABLE_YOUTUBE_AND_TWITCH
|
|
98
|
+
? getDomDetailsForTwitch()
|
|
99
|
+
: getDomDetailsForLighstparkDemo();
|
|
100
|
+
|
|
101
|
+
if (parseResponse) {
|
|
102
|
+
currentTrackingDetails = parseResponse.trackingDetails;
|
|
103
|
+
startListeningToVideoEvents(parseResponse.videoElement);
|
|
104
|
+
chrome.runtime.sendMessage({
|
|
105
|
+
...parseResponse.trackingDetails,
|
|
106
|
+
id: "video_details",
|
|
107
|
+
});
|
|
108
|
+
if (isLightsparkDemo) {
|
|
109
|
+
updateWalletBalances();
|
|
110
|
+
}
|
|
111
|
+
} else if (numRetries < 10) {
|
|
112
|
+
// Retry in a second to see if the page loads.
|
|
113
|
+
// TODO: Consider whether we need to use a navigation listener to detect video page changes for SPAs where the
|
|
114
|
+
// load event won't re-fire.
|
|
115
|
+
setTimeout(() => afterDOMLoaded(numRetries + 1), 1000);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
if (document.readyState === "loading") {
|
|
120
|
+
document.addEventListener("DOMContentLoaded", () => afterDOMLoaded(0));
|
|
121
|
+
} else {
|
|
122
|
+
afterDOMLoaded(0);
|
|
123
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CurrencyAmount,
|
|
3
|
+
Transaction,
|
|
4
|
+
TransactionStatus,
|
|
5
|
+
} from "@lightsparkdev/lightspark-sdk";
|
|
6
|
+
|
|
7
|
+
type Balances = {
|
|
8
|
+
viewerBalance: CurrencyAmount;
|
|
9
|
+
creatorBalance: CurrencyAmount;
|
|
10
|
+
};
|
|
11
|
+
let initialBalances: Balances | null = null;
|
|
12
|
+
|
|
13
|
+
export const updateWalletBalances = async () => {
|
|
14
|
+
const { balances } = await getWalletBalances();
|
|
15
|
+
initialBalances = balances;
|
|
16
|
+
renderBalances(balances);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const renderBalances = async (balances: Balances | null) => {
|
|
20
|
+
if (!balances) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
window.postMessage(
|
|
24
|
+
{
|
|
25
|
+
type: "FROM_CONTENT_SCRIPT",
|
|
26
|
+
id: "balances_changed",
|
|
27
|
+
viewerBalance: balances.viewerBalance,
|
|
28
|
+
creatorBalance: balances.creatorBalance,
|
|
29
|
+
},
|
|
30
|
+
"*"
|
|
31
|
+
);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const transactions = new Map<string, Transaction>();
|
|
35
|
+
|
|
36
|
+
export const updateTransactionRows = async (
|
|
37
|
+
changedTransactions: Transaction[]
|
|
38
|
+
) => {
|
|
39
|
+
changedTransactions.forEach((transaction) => {
|
|
40
|
+
transactions.set(transaction.id, transaction);
|
|
41
|
+
});
|
|
42
|
+
const sortedTransactions = Array.from(transactions.values()).sort((a, b) =>
|
|
43
|
+
b.createdAt.localeCompare(a.createdAt)
|
|
44
|
+
);
|
|
45
|
+
window.postMessage(
|
|
46
|
+
{
|
|
47
|
+
type: "FROM_CONTENT_SCRIPT",
|
|
48
|
+
id: "transactions_changed",
|
|
49
|
+
transactions: sortedTransactions,
|
|
50
|
+
},
|
|
51
|
+
"*"
|
|
52
|
+
);
|
|
53
|
+
fakeBalanceChanges();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const fakeBalanceChanges = () => {
|
|
57
|
+
if (!initialBalances) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
console.log("initialBalances", JSON.stringify(initialBalances));
|
|
62
|
+
let viewerBalance = initialBalances.viewerBalance;
|
|
63
|
+
let creatorBalance = initialBalances.creatorBalance;
|
|
64
|
+
for (const t of Array.from(transactions.values())) {
|
|
65
|
+
if (t.status !== TransactionStatus.SUCCESS) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (
|
|
70
|
+
t.amount.preferredCurrencyUnit !== viewerBalance.preferredCurrencyUnit ||
|
|
71
|
+
t.amount.originalUnit !== viewerBalance.originalUnit
|
|
72
|
+
) {
|
|
73
|
+
console.warn("Transaction amount units do not match wallet balance");
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
viewerBalance = addCurrencyAmounts(viewerBalance, negativeAmount(t.amount));
|
|
78
|
+
creatorBalance = addCurrencyAmounts(creatorBalance, t.amount);
|
|
79
|
+
}
|
|
80
|
+
console.log("new values", JSON.stringify({ viewerBalance, creatorBalance }));
|
|
81
|
+
renderBalances({ viewerBalance, creatorBalance });
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const addCurrencyAmounts = (
|
|
85
|
+
amount1: CurrencyAmount,
|
|
86
|
+
amount2: CurrencyAmount
|
|
87
|
+
) => {
|
|
88
|
+
return {
|
|
89
|
+
...amount1,
|
|
90
|
+
originalValue: amount1.originalValue + amount2.originalValue,
|
|
91
|
+
preferredCurrencyValueApprox:
|
|
92
|
+
amount1.preferredCurrencyValueApprox +
|
|
93
|
+
amount2.preferredCurrencyValueApprox,
|
|
94
|
+
preferredCurrencyValueRounded:
|
|
95
|
+
amount1.preferredCurrencyValueRounded +
|
|
96
|
+
amount2.preferredCurrencyValueRounded,
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const negativeAmount = (amount: CurrencyAmount) => {
|
|
101
|
+
return {
|
|
102
|
+
...amount,
|
|
103
|
+
originalValue: -amount.originalValue,
|
|
104
|
+
preferredCurrencyValueApprox: -amount.preferredCurrencyValueApprox,
|
|
105
|
+
preferredCurrencyValueRounded: -amount.preferredCurrencyValueRounded,
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const getWalletBalances = () => {
|
|
110
|
+
return chrome.runtime.sendMessage({
|
|
111
|
+
id: "get_streaming_wallet_balances",
|
|
112
|
+
}) as Promise<{ balances: any }>;
|
|
113
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ChannelSource, VideoPlaybackUpdateMessage } from "../types/Messages";
|
|
2
|
+
|
|
3
|
+
type ParseResult = {
|
|
4
|
+
trackingDetails: VideoPlaybackUpdateMessage;
|
|
5
|
+
videoElement: HTMLVideoElement;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const getDomDetailsForYoutube = (): ParseResult | null => {
|
|
9
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
10
|
+
if (!searchParams.has("v")) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const userLink = document.querySelector(
|
|
14
|
+
".ytd-watch-metadata .ytd-channel-name a"
|
|
15
|
+
) as HTMLAnchorElement;
|
|
16
|
+
const videoElement = document.querySelector(
|
|
17
|
+
"#movie_player video"
|
|
18
|
+
) as HTMLVideoElement;
|
|
19
|
+
if (!userLink || !videoElement) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const newTrackingDetails = {
|
|
23
|
+
videoID: searchParams.get("v") || "",
|
|
24
|
+
videoName:
|
|
25
|
+
(document.querySelector('meta[name="title"]') as HTMLMetaElement)
|
|
26
|
+
?.content ||
|
|
27
|
+
document.querySelector("title")?.textContent ||
|
|
28
|
+
"",
|
|
29
|
+
channelID: userLink.href.slice(
|
|
30
|
+
userLink.href.indexOf("/channel/") + "/channel/".length
|
|
31
|
+
),
|
|
32
|
+
channelName: userLink.textContent || "",
|
|
33
|
+
channelSource: ChannelSource.youtube,
|
|
34
|
+
progress: 0,
|
|
35
|
+
duration: videoElement?.duration || 0,
|
|
36
|
+
isPlaying: !videoElement.paused,
|
|
37
|
+
};
|
|
38
|
+
return { trackingDetails: newTrackingDetails, videoElement };
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const getDomDetailsForTwitch = (): ParseResult | null => {
|
|
42
|
+
let videoID = "livestream";
|
|
43
|
+
if (window.location.pathname.includes("/videos/")) {
|
|
44
|
+
const index = window.location.pathname.lastIndexOf("/videos/");
|
|
45
|
+
videoID = window.location.pathname.slice(index + "/videos/".length);
|
|
46
|
+
// TODO(Jeremy): If we only care about live, probably just return null here.
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// There may be a better way to do this, but the class names in twitch are obfuscated :-/.
|
|
50
|
+
const userLink = Array.from(
|
|
51
|
+
document.querySelectorAll(".channel-info-content a")
|
|
52
|
+
).filter((it) => {
|
|
53
|
+
return it.classList.length === 0;
|
|
54
|
+
})[0] as HTMLAnchorElement;
|
|
55
|
+
const videoElement = document.querySelector(
|
|
56
|
+
".video-player video"
|
|
57
|
+
) as HTMLVideoElement;
|
|
58
|
+
|
|
59
|
+
const newTrackingDetails = {
|
|
60
|
+
videoID: videoID,
|
|
61
|
+
videoName:
|
|
62
|
+
document.querySelector('*[data-a-target="stream-title"]')?.textContent ||
|
|
63
|
+
"",
|
|
64
|
+
channelID: userLink?.href?.slice(userLink?.href.lastIndexOf("/") + 1) || "",
|
|
65
|
+
channelName: userLink?.textContent || "",
|
|
66
|
+
channelSource: ChannelSource.twitch,
|
|
67
|
+
progress: 0,
|
|
68
|
+
duration: videoElement?.duration || 0,
|
|
69
|
+
isPlaying: !videoElement.paused,
|
|
70
|
+
};
|
|
71
|
+
return { trackingDetails: newTrackingDetails, videoElement };
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const getDomDetailsForLighstparkDemo = (): ParseResult | null => {
|
|
75
|
+
const videoElement = document.querySelector(
|
|
76
|
+
"video#stream-sats-video"
|
|
77
|
+
) as HTMLVideoElement;
|
|
78
|
+
if (!videoElement) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const newTrackingDetails = {
|
|
82
|
+
videoID: "ls_demo",
|
|
83
|
+
videoName: "Lightspark Streaming Demo",
|
|
84
|
+
channelID: "ls",
|
|
85
|
+
channelName: "Lightspark",
|
|
86
|
+
channelSource: ChannelSource.lightspark,
|
|
87
|
+
progress: 0,
|
|
88
|
+
duration: videoElement?.duration || 0,
|
|
89
|
+
isPlaying: !videoElement.paused,
|
|
90
|
+
};
|
|
91
|
+
return { trackingDetails: newTrackingDetails, videoElement };
|
|
92
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
body {
|
|
2
|
+
width: 300px;
|
|
3
|
+
height: 380px;
|
|
4
|
+
margin: 0;
|
|
5
|
+
font-family: "Montserrat", sans-serif;
|
|
6
|
+
font-weight: 500;
|
|
7
|
+
-webkit-font-smoothing: antialiased;
|
|
8
|
+
-moz-osx-font-smoothing: grayscale;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
#root {
|
|
12
|
+
height: 100%;
|
|
13
|
+
width: 100%;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
}
|