Skip to content
This repository was archived by the owner on Dec 21, 2024. It is now read-only.

Commit cd12d07

Browse files
sven-hashcgi-bin
andauthored
Feat/expired paste (#61)
* support expiration paste * add: support expired paste Co-authored-by: cgi-bin <[email protected]>
1 parent 92df670 commit cd12d07

File tree

4 files changed

+180
-15
lines changed

4 files changed

+180
-15
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Texts.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ class Texts extends React.Component {
258258
is_burn: data['is_burn'],
259259
is_ipfs: data['is_ipfs'],
260260
burn_view: data['burn_view'],
261+
expiration_time: data['expiration_time'],
262+
expiration_height: data['expiration_height']
261263
})
262264

263265
// Display text if any
@@ -439,6 +441,8 @@ class Texts extends React.Component {
439441
num_view={this.state.num_view}
440442
created_on={this.state.created_on}
441443
is_ipfs={this.state.is_ipfs}
444+
expiration_time={this.state.expiration_time}
445+
expiration_height={this.state.expiration_height}
442446
/>
443447
) : (
444448
''

src/UserInput.js

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ import Tab from '@mui/joy/Tab'
3333
import MarkdownViewer from './components/MarkdownViewer'
3434
import Autocomplete from '@mui/material/Autocomplete'
3535
import TextField from '@mui/material/TextField'
36+
import { Thermostat } from '@mui/icons-material'
37+
38+
const EXPIRATION_BITCOIN_HEIGHT = process.env.EXPIRATION_BITCOIN_HEIGHT || 'false'
39+
3640

3741
const muiTheme = extendMuiTheme({
3842
// This is required to point to `var(--joy-*)` because we are using `CssVarsProvider` from Joy UI.
@@ -136,6 +140,9 @@ class UserInput extends React.Component {
136140
limitSize: 120_0000,
137141
mdPreview: false,
138142
burnView: 0,
143+
expirationChecked: false,
144+
expirationTimeRelative: '',
145+
expirationHeightRelative: null,
139146
}
140147

141148
this.files = null
@@ -148,6 +155,27 @@ class UserInput extends React.Component {
148155
{ view: '256' },
149156
]
150157

158+
this.expirationRelativeTimeOption = [
159+
{ time: '5 minutes' },
160+
{ time: '10 minutes' },
161+
{ time: '30 minutes' },
162+
{ time: '1 hour' },
163+
{ time: '12 hours' },
164+
{ time: '1 week' },
165+
{ time: '1 month' },
166+
{ time: '6 months' },
167+
]
168+
169+
this.expirationRelativeHeightOption = [
170+
{ height: '1 block', value: 1 },
171+
{ height: '5 blocks', value: 5 },
172+
{ height: '10 blocks', value: 10 },
173+
{ height: '50 blocks', value: 50 },
174+
{ height: '100 blocks', value: 100 },
175+
{ height: '256 blocks', value: 256 },
176+
{ height: '500 blocks', value: 500 },
177+
]
178+
151179
// Instanciating a new encryptor will generate new key by default
152180
this.encryptor = new E2EEncryptor()
153181

@@ -414,6 +442,12 @@ class UserInput extends React.Component {
414442
burn_view: parseInt(this.state.burnView),
415443
encParams: this.state.isPrivate ? encrypted[1] : '',
416444
ipfs: this.state.isIpfs,
445+
expiration_time: this.state.expirationTimeRelative,
446+
expiration_height: this.state.expirationHeightRelative
447+
? parseInt(
448+
this.state.expirationHeightRelative.split(' ')[0]
449+
)
450+
: null,
417451
},
418452
}
419453

@@ -437,8 +471,8 @@ class UserInput extends React.Component {
437471
render() {
438472
return (
439473
<CssVarsProvider theme={theme}>
440-
<Header/>
441-
<main style={{marginRight: '10px', marginLeft:'10px'}}>
474+
<Header />
475+
<main style={{ marginRight: '10px', marginLeft: '10px' }}>
442476
<Sheet
443477
sx={{
444478
maxWidth: '950px',
@@ -560,6 +594,96 @@ class UserInput extends React.Component {
560594
''
561595
)}
562596

597+
<Tooltip
598+
title="Your message will be deleted after a time. Not compatible with IPFS upload."
599+
size="sm"
600+
placement="bottom"
601+
>
602+
<Checkbox
603+
onChange={(event) =>
604+
this.setState({
605+
expirationChecked:
606+
event.target.checked,
607+
})
608+
}
609+
disabled={this.state.isIpfs}
610+
size="sm"
611+
label="Expire in"
612+
checked={this.state.expirationChecked}
613+
/>
614+
</Tooltip>
615+
616+
{this.state.expirationChecked ? (
617+
<Autocomplete
618+
disablePortal
619+
onChange={(event, newValue) => {
620+
this.setState({
621+
expirationTimeRelative: newValue,
622+
})
623+
}}
624+
onInputChange={(event, newInputValue) => {
625+
this.setState({
626+
expirationTimeRelative:
627+
newInputValue,
628+
})
629+
}}
630+
options={this.expirationRelativeTimeOption.map(
631+
(option) => option.time
632+
)}
633+
freeSolo
634+
sx={{
635+
position: 'relative',
636+
top: '-13px',
637+
width: 150,
638+
fontSize: '12px',
639+
}}
640+
renderInput={(params) => (
641+
<TextField {...params} label="Time" />
642+
)}
643+
size="small"
644+
/>
645+
) : (
646+
''
647+
)}
648+
649+
{this.state.expirationChecked &&
650+
EXPIRATION_BITCOIN_HEIGHT ===
651+
'true' ? (
652+
<Autocomplete
653+
disablePortal
654+
onChange={(event, newValue) => {
655+
this.setState({
656+
expirationHeightRelative: newValue,
657+
})
658+
}}
659+
onInputChange={(event, newInputValue) => {
660+
this.setState({
661+
expirationHeightRelative:
662+
newInputValue,
663+
})
664+
}}
665+
options={this.expirationRelativeHeightOption.map(
666+
(option) => option.height
667+
)}
668+
freeSolo
669+
sx={{
670+
position: 'relative',
671+
top: '-13px',
672+
width: 150,
673+
fontSize: '12px',
674+
}}
675+
renderInput={(params) => (
676+
<TextField
677+
{...params}
678+
label="Block height"
679+
/>
680+
)}
681+
size="small"
682+
/>
683+
) : (
684+
''
685+
)}
686+
563687
<Tooltip
564688
title="Your message will not be encrypted"
565689
size="sm"

src/components/TextStats.js

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,56 @@ class TextStats extends React.Component {
2525
}}
2626
>
2727
{this.props.num_view
28-
? `Views: ` + this.props.num_view + ` - `
28+
? `Views: ` + this.props.num_view + ' - '
2929
: ''}
3030
{'Created on: ' +
31-
new Date(this.props.created_on).toLocaleString(navigator.language,{
32-
day: "2-digit",
33-
month: "2-digit",
34-
year: "2-digit",
35-
})
36-
}
31+
new Date(this.props.created_on).toLocaleString(
32+
navigator.language,
33+
{
34+
day: '2-digit',
35+
month: '2-digit',
36+
year: '2-digit',
37+
}
38+
)}
3739
</Typography>
38-
39-
{this.props.is_ipfs ? ' - ' : ''}
40-
{this.props.is_ipfs ? (
40+
41+
{this.props.expiration_time ? <>&nbsp;</> : ''}
42+
<Typography
43+
level="body2"
44+
sx={{
45+
display: 'inline-block',
46+
alignItems: 'flex-start',
47+
wordBreak: 'break-all',
48+
}}
49+
>
50+
{this.props.expiration_time
51+
? '- Expire on: ' +
52+
new Date(this.props.expiration_time).toLocaleString(
53+
navigator.language
54+
)
55+
: ''}
56+
</Typography>
57+
58+
59+
{this.props.expiration_height ? <>&nbsp;</> : ''}
60+
<Typography
61+
level="body2"
62+
sx={{
63+
display: 'inline-block',
64+
alignItems: 'flex-start',
65+
wordBreak: 'break-all',
66+
}}
67+
>
68+
{this.props.expiration_height
69+
? '- Expire block height: ' +
70+
new Date(this.props.expiration_height).toLocaleString(
71+
navigator.language
72+
)
73+
: ''}
74+
</Typography>
75+
76+
{this.props.is_ipfs ? ' - ' : ''}
77+
{this.props.is_ipfs ? (
4178
<Chip
4279
color={this.props.is_ipfs ? 'success' : 'neutral'}
4380
variant="soft"
@@ -51,7 +88,7 @@ class TextStats extends React.Component {
5188
}
5289
style={{ position: 'relative', top: '-2px' }}
5390
>
54-
IPFS
91+
IPFS
5592
</Chip>
5693
) : (
5794
''

0 commit comments

Comments
 (0)