Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
gab-social
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
gab
social
gab-social
Commits
81e8b329
Commit
81e8b329
authored
Aug 28, 2019
by
Rob Colbert
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of
https://code.gab.com/gab/social/gab-social
into develop
parents
29f324d4
d382c557
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
144 additions
and
73 deletions
+144
-73
README.md
README.md
+3
-3
app/javascript/gabsocial/actions/compose.js
app/javascript/gabsocial/actions/compose.js
+27
-27
app/javascript/gabsocial/actions/streaming.js
app/javascript/gabsocial/actions/streaming.js
+16
-0
app/javascript/gabsocial/components/extended_video_player.js
app/javascript/gabsocial/components/extended_video_player.js
+1
-1
app/javascript/gabsocial/components/media_gallery.js
app/javascript/gabsocial/components/media_gallery.js
+1
-0
app/javascript/gabsocial/components/status.js
app/javascript/gabsocial/components/status.js
+0
-1
app/javascript/gabsocial/containers/gabsocial.js
app/javascript/gabsocial/containers/gabsocial.js
+5
-1
app/javascript/gabsocial/features/account_gallery/components/media_item.js
...bsocial/features/account_gallery/components/media_item.js
+1
-0
app/javascript/gabsocial/features/status/components/card.js
app/javascript/gabsocial/features/status/components/card.js
+29
-19
app/javascript/gabsocial/features/video/index.js
app/javascript/gabsocial/features/video/index.js
+2
-0
app/javascript/styles/gabsocial/components.scss
app/javascript/styles/gabsocial/components.scss
+23
-12
app/services/fetch_link_card_service.rb
app/services/fetch_link_card_service.rb
+27
-9
streaming/index.js
streaming/index.js
+9
-0
No files found.
README.md
View file @
81e8b329
...
...
@@ -19,10 +19,10 @@ We have diverged from Mastodon in several ways in pursuit of our own goals.
1.
Quote posting
## BTCPay
In order to make BTC flow work, 3 envi
or
nment variables need to be set:
In order to make BTC flow work, 3 envi
ro
nment variables need to be set:
-
`BTCPAY_LEGACY_TOKEN`
: So called Legacy Tokens can be found in https://btcpay.
xxx.com/stores/yyy
/Tokens
-
`BTCPAY_PUB_KEY`
: Public key that is used when creating an access token or pairing https://btcpay.
xxx.com/stores/yyy
/Tokens/Create
-
`BTCPAY_LEGACY_TOKEN`
: So called Legacy Tokens can be found in https://btcpay.
[yourdomain].com/stores/[yourstore]
/Tokens
-
`BTCPAY_PUB_KEY`
: Public key that is used when creating an access token or pairing https://btcpay.
[yourdomain].com/stores/[yourstore]
/Tokens/Create
-
`BTCPAY_MERCHANT_TOKEN`
: Token created for facade
*merchant*
## Deployment
...
...
app/javascript/gabsocial/actions/compose.js
View file @
81e8b329
...
...
@@ -137,6 +137,32 @@ export function directCompose(account, routerHistory) {
};
};
export
function
handleComposeSubmit
(
dispatch
,
getState
,
response
,
status
)
{
if
(
!
dispatch
||
!
getState
)
return
;
dispatch
(
insertIntoTagHistory
(
response
.
data
.
tags
,
status
));
dispatch
(
submitComposeSuccess
({
...
response
.
data
}));
// To make the app more responsive, immediately push the status into the columns
const
insertIfOnline
=
timelineId
=>
{
const
timeline
=
getState
().
getIn
([
'
timelines
'
,
timelineId
]);
if
(
timeline
&&
timeline
.
get
(
'
items
'
).
size
>
0
&&
timeline
.
getIn
([
'
items
'
,
0
])
!==
null
&&
timeline
.
get
(
'
online
'
))
{
let
dequeueArgs
=
{};
if
(
timelineId
===
'
community
'
)
dequeueArgs
.
onlyMedia
=
getState
().
getIn
([
'
settings
'
,
'
community
'
,
'
other
'
,
'
onlyMedia
'
]);
dispatch
(
dequeueTimeline
(
timelineId
,
null
,
dequeueArgs
));
dispatch
(
updateTimeline
(
timelineId
,
{
...
response
.
data
}));
}
};
if
(
response
.
data
.
visibility
!==
'
direct
'
)
{
insertIfOnline
(
'
home
'
);
}
else
if
(
response
.
data
.
in_reply_to_id
===
null
&&
response
.
data
.
visibility
===
'
public
'
)
{
insertIfOnline
(
'
community
'
);
insertIfOnline
(
'
public
'
);
}
}
export
function
submitCompose
(
routerHistory
,
group
)
{
return
function
(
dispatch
,
getState
)
{
if
(
!
me
)
return
;
...
...
@@ -175,33 +201,7 @@ export function submitCompose(routerHistory, group) {
if
(
response
.
data
.
visibility
===
'
direct
'
&&
getState
().
getIn
([
'
conversations
'
,
'
mounted
'
])
<=
0
&&
routerHistory
)
{
routerHistory
.
push
(
'
/messages
'
);
}
dispatch
(
insertIntoTagHistory
(
response
.
data
.
tags
,
status
));
dispatch
(
submitComposeSuccess
({
...
response
.
data
}));
// To make the app more responsive, immediately push the status
// into the columns
const
insertIfOnline
=
timelineId
=>
{
const
timeline
=
getState
().
getIn
([
'
timelines
'
,
timelineId
]);
if
(
timeline
&&
timeline
.
get
(
'
items
'
).
size
>
0
&&
timeline
.
getIn
([
'
items
'
,
0
])
!==
null
&&
timeline
.
get
(
'
online
'
))
{
let
dequeueArgs
=
{};
if
(
timelineId
===
'
community
'
)
dequeueArgs
.
onlyMedia
=
getState
().
getIn
([
'
settings
'
,
'
community
'
,
'
other
'
,
'
onlyMedia
'
]),
dispatch
(
dequeueTimeline
(
timelineId
,
null
,
dequeueArgs
));
dispatch
(
updateTimeline
(
timelineId
,
{
...
response
.
data
}));
}
};
if
(
response
.
data
.
visibility
!==
'
direct
'
)
{
insertIfOnline
(
'
home
'
);
}
if
(
response
.
data
.
in_reply_to_id
===
null
&&
response
.
data
.
visibility
===
'
public
'
)
{
insertIfOnline
(
'
community
'
);
insertIfOnline
(
'
public
'
);
}
handleComposeSubmit
(
dispatch
,
getState
,
response
,
status
);
}).
catch
(
function
(
error
)
{
dispatch
(
submitComposeFail
(
error
));
});
...
...
app/javascript/gabsocial/actions/streaming.js
View file @
81e8b329
...
...
@@ -10,6 +10,7 @@ import { updateNotificationsQueue, expandNotifications } from './notifications';
import
{
updateConversations
}
from
'
./conversations
'
;
import
{
fetchFilters
}
from
'
./filters
'
;
import
{
getLocale
}
from
'
../locales
'
;
import
{
handleComposeSubmit
}
from
'
./compose
'
;
const
{
messages
}
=
getLocale
();
...
...
@@ -61,3 +62,18 @@ export const connectHashtagStream = (id, tag, accept) => connectTimelineStream
export
const
connectDirectStream
=
()
=>
connectTimelineStream
(
'
direct
'
,
'
direct
'
);
export
const
connectListStream
=
id
=>
connectTimelineStream
(
`list:
${
id
}
`
,
`list&list=
${
id
}
`
);
export
const
connectGroupStream
=
id
=>
connectTimelineStream
(
`group:
${
id
}
`
,
`group&group=
${
id
}
`
);
export
const
connectStatusUpdateStream
=
()
=>
{
return
connectStream
(
'
statuscard
'
,
null
,
(
dispatch
,
getState
)
=>
{
return
{
onConnect
()
{},
onDisconnect
()
{},
onReceive
(
data
)
{
if
(
!
data
[
'
event
'
]
||
!
data
[
'
payload
'
])
return
;
if
(
data
.
event
===
'
update
'
)
{
handleComposeSubmit
(
dispatch
,
getState
,
{
data
:
JSON
.
parse
(
data
.
payload
)},
null
)
}
},
};
});
}
\ No newline at end of file
app/javascript/gabsocial/components/extended_video_player.js
View file @
81e8b329
...
...
@@ -44,9 +44,9 @@ export default class ExtendedVideoPlayer extends React.PureComponent {
return
(
<
div
className
=
'
extended-video-player
'
>
<
video
playsInline
ref
=
{
this
.
setRef
}
src
=
{
src
}
autoPlay
role
=
'
button
'
tabIndex
=
'
0
'
aria
-
label
=
{
alt
}
...
...
app/javascript/gabsocial/components/media_gallery.js
View file @
81e8b329
...
...
@@ -189,6 +189,7 @@ class Item extends React.PureComponent {
autoPlay
=
{
autoPlay
}
loop
muted
playsInline
/>
<
span
className
=
'
media-gallery__gifv__label
'
>
GIF
<
/span
>
...
...
app/javascript/gabsocial/components/status.js
View file @
81e8b329
...
...
@@ -380,7 +380,6 @@ class Status extends ImmutablePureComponent {
<
Card
onOpenMedia
=
{
this
.
props
.
onOpenMedia
}
card
=
{
status
.
get
(
'
card
'
)}
compact
cacheWidth
=
{
this
.
props
.
cacheMediaWidth
}
defaultWidth
=
{
this
.
props
.
cachedMediaWidth
}
/
>
...
...
app/javascript/gabsocial/containers/gabsocial.js
View file @
81e8b329
...
...
@@ -11,7 +11,10 @@ import UI from '../features/ui';
import
Introduction
from
'
../features/introduction
'
;
import
{
fetchCustomEmojis
}
from
'
../actions/custom_emojis
'
;
import
{
hydrateStore
}
from
'
../actions/store
'
;
import
{
connectUserStream
}
from
'
../actions/streaming
'
;
import
{
connectUserStream
,
connectStatusUpdateStream
,
}
from
'
../actions/streaming
'
;
import
{
IntlProvider
,
addLocaleData
}
from
'
react-intl
'
;
import
{
getLocale
}
from
'
../locales
'
;
import
initialState
from
'
../initial_state
'
;
...
...
@@ -70,6 +73,7 @@ export default class GabSocial extends React.PureComponent {
componentDidMount
()
{
this
.
disconnect
=
store
.
dispatch
(
connectUserStream
());
store
.
dispatch
(
connectStatusUpdateStream
());
}
componentWillUnmount
()
{
...
...
app/javascript/gabsocial/features/account_gallery/components/media_item.js
View file @
81e8b329
...
...
@@ -127,6 +127,7 @@ export default class MediaItem extends ImmutablePureComponent {
autoPlay
=
{
autoPlay
}
loop
muted
playsInline
/>
<
span
className
=
'
media-gallery__gifv__label
'
>
GIF
<
/span
>
...
...
app/javascript/gabsocial/features/status/components/card.js
View file @
81e8b329
...
...
@@ -58,16 +58,12 @@ export default class Card extends React.PureComponent {
static
propTypes
=
{
card
:
ImmutablePropTypes
.
map
,
maxDescription
:
PropTypes
.
number
,
onOpenMedia
:
PropTypes
.
func
.
isRequired
,
compact
:
PropTypes
.
bool
,
defaultWidth
:
PropTypes
.
number
,
cacheWidth
:
PropTypes
.
func
,
};
static
defaultProps
=
{
maxDescription
:
50
,
compact
:
false
,
};
state
=
{
...
...
@@ -131,37 +127,52 @@ export default class Card extends React.PureComponent {
ref
=
{
this
.
setRef
}
className
=
'
status-card__image status-card-video
'
dangerouslySetInnerHTML
=
{
content
}
style
=
{{
height
}}
style
=
{{
height
,
paddingBottom
:
0
,
}}
/
>
);
}
render
()
{
const
{
card
,
maxDescription
,
compact
}
=
this
.
props
;
const
{
card
}
=
this
.
props
;
const
{
width
,
embedded
}
=
this
.
state
;
if
(
card
===
null
)
{
return
null
;
}
const
provider
=
card
.
get
(
'
provider_name
'
).
length
===
0
?
decodeIDNA
(
getHostname
(
card
.
get
(
'
url
'
)))
:
card
.
get
(
'
provider_name
'
);
const
horizontal
=
(
!
compact
&&
card
.
get
(
'
width
'
)
>
card
.
get
(
'
height
'
)
&&
(
card
.
get
(
'
width
'
)
+
100
>=
width
))
||
card
.
get
(
'
type
'
)
!==
'
link
'
||
embedded
;
const
maxDescription
=
150
;
const
cardImg
=
card
.
get
(
'
image
'
);
const
provider
=
card
.
get
(
'
provider_name
'
).
length
===
0
?
decodeIDNA
(
getHostname
(
card
.
get
(
'
url
'
)))
:
card
.
get
(
'
provider_name
'
);
const
horizontal
=
(
card
.
get
(
'
width
'
)
>
card
.
get
(
'
height
'
)
&&
(
card
.
get
(
'
width
'
)
+
100
>=
width
))
||
card
.
get
(
'
type
'
)
!==
'
link
'
||
embedded
;
const
interactive
=
card
.
get
(
'
type
'
)
!==
'
link
'
;
const
className
=
classnames
(
'
status-card
'
,
{
horizontal
,
compact
,
interactive
});
const
title
=
interactive
?
<
a
className
=
'
status-card__title
'
href
=
{
card
.
get
(
'
url
'
)}
title
=
{
card
.
get
(
'
title
'
)}
rel
=
'
noopener
'
target
=
'
_blank
'
><
strong
>
{
card
.
get
(
'
title
'
)}
<
/strong></
a
>
:
<
strong
className
=
'
status-card__title
'
title
=
{
card
.
get
(
'
title
'
)}
>
{
card
.
get
(
'
title
'
)}
<
/strong>
;
const
ratio
=
card
.
get
(
'
width
'
)
/
card
.
get
(
'
height
'
);
const
height
=
(
compact
&&
!
embedded
)
?
(
width
/
(
16
/
9
))
:
(
width
/
ratio
);
const
className
=
classnames
(
'
status-card
'
,
{
horizontal
,
interactive
,
compact
:
!
cardImg
,
});
const
title
=
interactive
?
<
a
className
=
'
status-card__title
'
href
=
{
card
.
get
(
'
url
'
)}
title
=
{
card
.
get
(
'
title
'
)}
rel
=
'
noopener
'
target
=
'
_blank
'
>
<
strong
>
{
card
.
get
(
'
title
'
)}
<
/strong
>
<
/a
>
:
<
strong
className
=
'
status-card__title
'
title
=
{
card
.
get
(
'
title
'
)}
>
{
card
.
get
(
'
title
'
)}
<
/strong>
;
const
description
=
(
<
div
className
=
'
status-card__content
'
>
{
title
}
{
!
(
horizontal
||
compact
)
&&
<
p
className
=
'
status-card__description
'
>
{
trim
(
card
.
get
(
'
description
'
)
||
''
,
maxDescription
)}
<
/p>
}
<
span
className
=
'
status-card__host
'
>
{
provider
}
<
/span
>
{
!
horizontal
&&
<
p
className
=
'
status-card__description
'
>
{
trim
(
card
.
get
(
'
description
'
)
||
''
,
maxDescription
)}
<
/p>
}
<
span
className
=
'
status-card__host
'
>
<
Icon
id
=
'
link
'
fixedWidth
/>
{
'
'
}
{
provider
}
<
/span
>
<
/div
>
);
let
embed
=
''
;
let
thumbnail
=
<
div
style
=
{{
backgroundImage
:
`url(
${
card
.
get
(
'
image
'
)}
)`
,
width
:
horizontal
?
width
:
null
,
height
:
horizontal
?
height
:
null
}}
className
=
'
status-card__image-image
'
/>
;
let
embed
=
''
;
let
thumbnail
=
<
div
style
=
{{
backgroundImage
:
`url(
${
card
Img
}
)`
}}
className
=
'
status-card__image-image
'
/>
;
if
(
interactive
)
{
if
(
embedded
)
{
...
...
@@ -176,7 +187,6 @@ export default class Card extends React.PureComponent {
embed
=
(
<
div
className
=
'
status-card__image
'
>
{
thumbnail
}
<
div
className
=
'
status-card__actions
'
>
<
div
>
<
button
onClick
=
{
this
.
handleEmbedClick
}
><
Icon
id
=
{
iconVariant
}
/></
button
>
...
...
@@ -190,10 +200,10 @@ export default class Card extends React.PureComponent {
return
(
<
div
className
=
{
className
}
ref
=
{
this
.
setRef
}
>
{
embed
}
{
!
compact
&&
description
}
{
description
}
<
/div
>
);
}
else
if
(
card
.
get
(
'
image
'
)
)
{
}
else
if
(
card
Img
)
{
embed
=
(
<
div
className
=
'
status-card__image
'
>
{
thumbnail
}
...
...
app/javascript/gabsocial/features/video/index.js
View file @
81e8b329
...
...
@@ -344,6 +344,7 @@ class Video extends React.PureComponent {
}
handleProgress
=
()
=>
{
if
(
!
this
.
video
.
buffered
)
return
;
if
(
this
.
video
.
buffered
.
length
>
0
)
{
this
.
setState
({
buffer
:
this
.
video
.
buffered
.
end
(
0
)
/
this
.
video
.
duration
*
100
});
}
...
...
@@ -432,6 +433,7 @@ class Video extends React.PureComponent {
<
canvas
width
=
{
32
}
height
=
{
32
}
ref
=
{
this
.
setCanvasRef
}
className
=
{
classNames
(
'
media-gallery__preview
'
,
{
'
media-gallery__preview--hidden
'
:
revealed
})}
/
>
{
revealed
&&
<
video
playsInline
ref
=
{
this
.
setVideoRef
}
src
=
{
src
}
poster
=
{
preview
}
...
...
app/javascript/styles/gabsocial/components.scss
View file @
81e8b329
...
...
@@ -2192,13 +2192,14 @@ a.account__display-name {
.status-card
{
display
:
flex
;
font-size
:
1
4
px
;
border
:
1px
solid
lighten
(
$ui-base-color
,
8
%
);
font-size
:
1
5
px
;
border
:
1px
solid
lighten
(
$ui-base-color
,
12
%
);
border-radius
:
4px
;
color
:
$dark-text-color
;
margin-top
:
14px
;
text-decoration
:
none
;
overflow
:
hidden
;
flex-direction
:
column
;
&
__actions
{
bottom
:
0
;
...
...
@@ -2274,7 +2275,7 @@ a.status-card {
display
:
block
;
font-weight
:
500
;
margin-bottom
:
5px
;
color
:
$
darker
-text-color
;
color
:
$
primary
-text-color
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
...
...
@@ -2284,26 +2285,33 @@ a.status-card {
.status-card__content
{
flex
:
1
1
auto
;
overflow
:
hidden
;
padding
:
14px
14px
14px
8px
;
padding
:
12px
10px
;
border-top
:
1px
solid
lighten
(
$ui-base-color
,
12%
);
}
.status-card__description
{
display
:
-
webkit-box
;
-webkit-line-clamp
:
2
;
-webkit-box-orient
:
vertical
;
max-height
:
40px
;
overflow
:
hidden
;
color
:
$darker-text-color
;
}
.status-card__host
{
display
:
block
;
margin-top
:
5px
;
font-size
:
13px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
color
:
$darker-text-color
;
}
.status-card__image
{
flex
:
0
0
100px
;
background
:
lighten
(
$ui-base-color
,
8%
)
;
display
:
block
;
padding-bottom
:
52
.25%
;
position
:
relative
;
background
:
lighten
(
$ui-base-color
,
8%
);
&
>
.fa
{
font-size
:
21px
;
...
...
@@ -2332,7 +2340,7 @@ a.status-card {
}
.status-card.compact
{
border-color
:
lighten
(
$ui-base-color
,
4%
)
;
flex-direction
:
row
;
&
.interactive
{
border
:
0
;
...
...
@@ -2348,7 +2356,8 @@ a.status-card {
}
.status-card__image
{
flex
:
0
0
60px
;
flex
:
0
0
94px
;
padding-bottom
:
0
;
}
}
...
...
@@ -2357,11 +2366,13 @@ a.status-card.compact:hover {
}
.status-card__image-image
{
border-radius
:
4px
0
0
4px
;
display
:
block
;
position
:
absolute
;
right
:
0
;
left
:
0
;
top
:
0
;
bottom
:
0
;
margin
:
0
;
width
:
100%
;
height
:
100%
;
object-fit
:
cover
;
background-size
:
cover
;
background-position
:
center
center
;
...
...
app/services/fetch_link_card_service.rb
View file @
81e8b329
...
...
@@ -15,7 +15,15 @@ class FetchLinkCardService < BaseService
@status
=
status
@url
=
parse_urls
return
if
@url
.
nil?
||
@status
.
preview_cards
.
any?
if
@status
.
preview_cards
.
any?
if
@url
.
nil?
detach_card
return
end
return
if
@status
.
preview_cards
.
first
.
url
==
@url
end
return
if
@url
.
nil?
@url
=
@url
.
to_s
...
...
@@ -39,12 +47,6 @@ class FetchLinkCardService < BaseService
def
process_url
@card
||=
PreviewCard
.
new
(
url:
@url
)
failed
=
Request
.
new
(
:head
,
@url
).
perform
do
|
res
|
res
.
code
!=
405
&&
res
.
code
!=
501
&&
(
res
.
code
!=
200
||
res
.
mime_type
!=
'text/html'
)
end
return
if
failed
Request
.
new
(
:get
,
@url
).
perform
do
|
res
|
if
res
.
code
==
200
&&
res
.
mime_type
==
'text/html'
@html
=
res
.
body_with_limit
...
...
@@ -55,13 +57,23 @@ class FetchLinkCardService < BaseService
end
end
return
if
@html
.
nil?
if
@html
.
nil?
detach_card
return
end
attempt_oembed
||
attempt_opengraph
end
def
attach_card
@status
.
preview_cards
<<
@card
@status
.
preview_cards
=
[
@card
]
send_status_update_payload
(
@status
)
Rails
.
cache
.
delete
(
@status
)
end
def
detach_card
@status
.
preview_cards
=
[]
send_status_update_payload
(
@status
)
Rails
.
cache
.
delete
(
@status
)
end
...
...
@@ -171,4 +183,10 @@ class FetchLinkCardService < BaseService
def
lock_options
{
redis:
Redis
.
current
,
key:
"fetch:
#{
@url
}
"
}
end
def
send_status_update_payload
(
status
)
@payload
=
InlineRenderer
.
render
(
status
,
nil
,
:status
)
@payload
=
Oj
.
dump
(
event: :update
,
payload:
@payload
)
Redis
.
current
.
publish
(
'statuscard'
,
@payload
)
end
end
streaming/index.js
View file @
81e8b329
...
...
@@ -534,6 +534,11 @@ const startWorker = (workerId) => {
app
.
use
(
authenticationMiddleware
);
app
.
use
(
errorMiddleware
);
app
.
get
(
'
/api/v1/streaming/statuscard
'
,
(
req
,
res
)
=>
{
const
channel
=
`statuscard`
;
streamFrom
(
channel
,
req
,
streamToHttp
(
req
,
res
),
streamHttpEnd
(
req
,
subscriptionHeartbeat
(
channel
)));
});
app
.
get
(
'
/api/v1/streaming/user
'
,
(
req
,
res
)
=>
{
const
channel
=
`timeline:
${
req
.
accountId
}
`
;
streamFrom
(
channel
,
req
,
streamToHttp
(
req
,
res
),
streamHttpEnd
(
req
,
subscriptionHeartbeat
(
channel
)));
...
...
@@ -608,6 +613,10 @@ const startWorker = (workerId) => {
let
channel
;
switch
(
location
.
query
.
stream
)
{
case
'
statuscard
'
:
channel
=
`statuscard`
;
streamFrom
(
channel
,
req
,
streamToWs
(
req
,
ws
),
streamWsEnd
(
req
,
ws
,
subscriptionHeartbeat
(
channel
)));
break
;
case
'
user
'
:
channel
=
`timeline:
${
req
.
accountId
}
`
;
streamFrom
(
channel
,
req
,
streamToWs
(
req
,
ws
),
streamWsEnd
(
req
,
ws
,
subscriptionHeartbeat
(
channel
)));
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment