@@ -8,7 +8,15 @@ import { v4 as uuid } from 'uuid';
8
8
import { get as nodecg } from './util/nodecg' ;
9
9
import obs from './util/obs' ;
10
10
import { mq } from './util/rabbitmq' ;
11
- import { assetsDonationAlertAssets , bids , donationAlerts , donationTotalMilestones , omnibar , prizes } from './util/replicants' ;
11
+ import {
12
+ assetsDonationAlertAssets ,
13
+ bids ,
14
+ donationAlerts ,
15
+ donationTotalMilestones ,
16
+ omnibar ,
17
+ prizes ,
18
+ soloedBidID ,
19
+ } from './util/replicants' ;
12
20
import { sc } from './util/speedcontrol' ;
13
21
14
22
const config = nodecg ( ) . bundleConfig ;
@@ -20,6 +28,7 @@ function filterUpcomingRuns(run: RunData): boolean {
20
28
21
29
// Gets next upcoming run from the cache (after refilling it if needed).
22
30
let upcomingRunsCache : RunData [ ] = [ ] ;
31
+
23
32
function getUpcomingRun ( ) : RunData | undefined {
24
33
// Filter out any already passed runs (according to schedule) from cache.
25
34
upcomingRunsCache = upcomingRunsCache . filter ( filterUpcomingRuns ) ;
@@ -38,6 +47,7 @@ function filterPrizes(prize: Prizes[0]): boolean {
38
47
39
48
// Gets next currently active prize from the cache (after refilling it if needed).
40
49
let prizesCache : Prizes = [ ] ;
50
+
41
51
function getPrize ( ) : Prizes [ 0 ] | undefined {
42
52
// Filter out any currently inactive prizes from cache.
43
53
prizesCache = prizesCache . filter ( filterPrizes ) ;
@@ -54,6 +64,20 @@ let lastBidId = -1;
54
64
function getClonedBid ( ) : Bids [ 0 ] | undefined {
55
65
// Just return nothing if there are no bids to show.
56
66
if ( ! bids . value . length ) return undefined ;
67
+
68
+ // if we have a solo, show that one
69
+ if ( soloedBidID . value ) {
70
+ const soloedBid = clone ( bids . value ) . find ( ( b ) => b . id === soloedBidID . value ) ;
71
+
72
+ // Make sure the bid id actually exists.
73
+ if ( soloedBid ) {
74
+ return soloedBid ;
75
+ }
76
+
77
+ // remove the solo if the bid was deleted
78
+ soloedBidID . value = null ;
79
+ }
80
+
57
81
let filtered = clone ( bids . value ) . filter ( ( b ) => b . id !== lastBidId ) ;
58
82
if ( ! filtered . length ) filtered = clone ( bids . value ) ;
59
83
const choices = filtered . reduce < { bid : Bids [ 0 ] , cumulativeWeight : number } [ ] > ( ( prev , bid ) => {
@@ -75,6 +99,7 @@ function getClonedBid(): Bids[0] | undefined {
75
99
76
100
// Gets a random active milestone.
77
101
let lastMilestoneId = '' ;
102
+
78
103
function getMilestone ( ) : DonationTotalMilestones [ 0 ] | undefined {
79
104
const active = clone ( donationTotalMilestones . value ) . filter ( ( m ) => m . enabled && m . amount ) ;
80
105
// Just return nothing if there are no active milestones to show.
@@ -88,6 +113,7 @@ function getMilestone(): DonationTotalMilestones[0] | undefined {
88
113
}
89
114
90
115
let loopsWithoutResult = 0 ;
116
+
91
117
async function showNext ( ) : Promise < void > {
92
118
// If there is a pin to start showing.
93
119
const { pin } = omnibar . value ;
@@ -130,7 +156,7 @@ async function showNext(): Promise<void> {
130
156
omnibar . value . pin = null ;
131
157
// showNext(); This is done in the "omnibar" replicant change listener
132
158
}
133
- // If there is alerts in the queue to show.
159
+ // If there is alerts in the queue to show.
134
160
} else if ( omnibar . value . alertQueue . length ) {
135
161
const alert = omnibar . value . alertQueue . shift ( ) ;
136
162
if ( alert ) {
@@ -176,9 +202,15 @@ async function showNext(): Promise<void> {
176
202
loopsWithoutResult += 1 ;
177
203
if ( next . type === 'UpcomingRun' ) {
178
204
const run = getUpcomingRun ( ) ;
179
- if ( ! run ) { showNext ( ) ; return ; }
180
- omnibar . value . current = { ...next ,
181
- props : { ...next . props ,
205
+ if ( ! run ) {
206
+ showNext ( ) ;
207
+ return ;
208
+ }
209
+
210
+ omnibar . value . current = {
211
+ ...next ,
212
+ props : {
213
+ ...next . props ,
182
214
run,
183
215
dash : {
184
216
text : 'Up next' ,
@@ -190,13 +222,23 @@ async function showNext(): Promise<void> {
190
222
} ;
191
223
} else if ( next . type === 'Prize' ) {
192
224
const prize = getPrize ( ) ;
193
- if ( ! prize ) { showNext ( ) ; return ; }
225
+ if ( ! prize ) {
226
+ showNext ( ) ;
227
+ return ;
228
+ }
229
+
194
230
omnibar . value . current = { ...next , props : { ...next . props , prize } } ;
195
231
} else if ( next . type === 'Milestone' ) {
196
232
const milestone = getMilestone ( ) ;
197
- if ( ! milestone ) { showNext ( ) ; return ; }
198
- omnibar . value . current = { ...next ,
199
- props : { ...next . props ,
233
+ if ( ! milestone ) {
234
+ showNext ( ) ;
235
+ return ;
236
+ }
237
+
238
+ omnibar . value . current = {
239
+ ...next ,
240
+ props : {
241
+ ...next . props ,
200
242
milestone,
201
243
dash : {
202
244
text : 'Upcoming Milestone' ,
@@ -207,8 +249,14 @@ async function showNext(): Promise<void> {
207
249
} ;
208
250
} else if ( next . type === 'Bid' ) {
209
251
const bid = getClonedBid ( ) ;
210
- if ( ! bid ) { showNext ( ) ; return ; }
211
- omnibar . value . current = { ...next ,
252
+
253
+ if ( ! bid ) {
254
+ showNext ( ) ;
255
+ return ;
256
+ }
257
+
258
+ omnibar . value . current = {
259
+ ...next ,
212
260
props : {
213
261
...next . props ,
214
262
bid,
@@ -249,8 +297,8 @@ omnibar.on('change', (newVal, oldVal) => {
249
297
// If nothing is currently being shown, and the rotation is filled from being empty,
250
298
// or we get alerts in the queue, trigger the cycle to start up again.
251
299
if ( ! newVal . current && oldVal
252
- && ( ( newVal . rotation . length && ! oldVal . rotation . length )
253
- || ( newVal . alertQueue . length && ! oldVal . alertQueue . length ) ) ) {
300
+ && ( ( newVal . rotation . length && ! oldVal . rotation . length )
301
+ || ( newVal . alertQueue . length && ! oldVal . alertQueue . length ) ) ) {
254
302
showNext ( ) ;
255
303
}
256
304
@@ -304,7 +352,7 @@ nodecg().listenFor('omnibarPlaySound', async (data: { amount?: number } | undefi
304
352
sourceName : config . obs . names . sources . donationSound ,
305
353
} ) ;
306
354
nodecg ( ) . log . debug ( '[Omnibar] omnibarPlaySound media restarted' ) ;
307
- // If different, explicitily set it. This also starts the playback.
355
+ // If different, explicitily set it. This also starts the playback.
308
356
} else {
309
357
await obs . conn . send ( 'SetSourceSettings' , {
310
358
sourceName : config . obs . names . sources . donationSound ,
0 commit comments