incyclist-services 1.6.6 → 1.6.7
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/lib/activities/active-rides/service.d.ts +8 -0
- package/lib/activities/active-rides/service.js +82 -3
- package/lib/activities/active-rides/types.d.ts +5 -0
- package/lib/ride/route/FreeRideDisplayService.js +1 -0
- package/lib/ride/route/RouteDisplayService.js +15 -9
- package/lib/routes/free-ride/service.js +20 -10
- package/lib/routes/list/cards/RouteCard.d.ts +3 -0
- package/lib/routes/list/cards/RouteCard.js +12 -1
- package/lib/routes/list/service.d.ts +4 -1
- package/lib/routes/list/service.js +20 -1
- package/lib/routes/list/types.d.ts +5 -0
- package/lib/video/VideoSyncHelper.js +25 -11
- package/lib/video/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { Observer } from "../../base/types";
|
|
|
3
3
|
import { CoachesService } from "../../coaches";
|
|
4
4
|
import { OnlineStateMonitoringService } from "../../monitoring";
|
|
5
5
|
import { RouteListService } from "../../routes";
|
|
6
|
+
import { ActiveRideCount } from "../../routes/list/types";
|
|
6
7
|
import { UserSettingsService } from "../../settings";
|
|
7
8
|
import { ActivityRouteType } from "../base";
|
|
8
9
|
import { IncyclistActiveRidesApi } from "../base/api/active-rides";
|
|
@@ -25,6 +26,8 @@ export declare class ActiveRidesService extends IncyclistService {
|
|
|
25
26
|
protected mq: ActiveRideListMessageQueue;
|
|
26
27
|
protected prevLogTS: number;
|
|
27
28
|
protected isStarted: boolean;
|
|
29
|
+
protected routeListObserver: Observer;
|
|
30
|
+
protected routesStats: ActiveRideCount[];
|
|
28
31
|
protected readonly activityEventHandlers: {
|
|
29
32
|
update: any;
|
|
30
33
|
start: any;
|
|
@@ -36,6 +39,9 @@ export declare class ActiveRidesService extends IncyclistService {
|
|
|
36
39
|
get(): ActiveRideEntry[];
|
|
37
40
|
getObserver(): Observer;
|
|
38
41
|
stop(): void;
|
|
42
|
+
protected countRidesByRoute(): Map<string, number>;
|
|
43
|
+
protected onRoutePageOpened(observer: Observer): Promise<void>;
|
|
44
|
+
protected getActiveRideCounts(): Promise<ActiveRideCount[]>;
|
|
39
45
|
protected start(session: string): void;
|
|
40
46
|
protected initList(): Promise<void>;
|
|
41
47
|
protected onActivityUpdated(): void;
|
|
@@ -70,8 +76,10 @@ export declare class ActiveRidesService extends IncyclistService {
|
|
|
70
76
|
initial: boolean;
|
|
71
77
|
}): Promise<void>;
|
|
72
78
|
protected subscribeActivityEvents(): Promise<void>;
|
|
79
|
+
protected onInfoEvent(topic: string): void;
|
|
73
80
|
protected onActivityEvent(topic: string, payload: ActiveRideListMessage): void;
|
|
74
81
|
protected publishStartEvent(): void;
|
|
82
|
+
protected onActivityInfoEvent(session: string): void;
|
|
75
83
|
protected onActivityStartEvent(session: string, payload: ActivityStartMessage): void;
|
|
76
84
|
protected getRemoteActivityDetails(sessionId: string): Promise<ActiveRideEntry>;
|
|
77
85
|
protected publishUpdateEvent(payload: any): void;
|
|
@@ -80,11 +80,17 @@ let ActiveRidesService = (() => {
|
|
|
80
80
|
this.apiState = { busy: false };
|
|
81
81
|
this.prevLogTS = 0;
|
|
82
82
|
this.isStarted = false;
|
|
83
|
+
this.routesStats = [];
|
|
83
84
|
this.activityEventHandlers = {
|
|
84
85
|
update: this.onActivityUpdateEvent.bind(this),
|
|
85
86
|
start: this.onActivityStartEvent.bind(this),
|
|
86
87
|
stop: this.onActivityStopEvent.bind(this)
|
|
87
88
|
};
|
|
89
|
+
const routeList = this.getRouteList();
|
|
90
|
+
routeList.on('opened', this.onRoutePageOpened.bind(this));
|
|
91
|
+
routeList.on('closed', () => {
|
|
92
|
+
delete this.routeListObserver;
|
|
93
|
+
});
|
|
88
94
|
}
|
|
89
95
|
init(session, maxLength = 10) {
|
|
90
96
|
this.maxLength = maxLength;
|
|
@@ -141,6 +147,56 @@ let ActiveRidesService = (() => {
|
|
|
141
147
|
this.logError(err, 'stop');
|
|
142
148
|
}
|
|
143
149
|
}
|
|
150
|
+
countRidesByRoute() {
|
|
151
|
+
const map = new Map();
|
|
152
|
+
const rides = this.get();
|
|
153
|
+
rides.forEach(ride => {
|
|
154
|
+
const routeHash = ride.ride.routeHash;
|
|
155
|
+
if (!map.has(routeHash)) {
|
|
156
|
+
map.set(routeHash, 0);
|
|
157
|
+
}
|
|
158
|
+
const count = map.get(routeHash);
|
|
159
|
+
map.set(routeHash, count + 1);
|
|
160
|
+
});
|
|
161
|
+
return map;
|
|
162
|
+
}
|
|
163
|
+
onRoutePageOpened(observer) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
this.routeListObserver = observer;
|
|
166
|
+
yield this.getActiveRideCounts();
|
|
167
|
+
this.routeListObserver.emit('stats-update', this.routesStats);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
getActiveRideCounts() {
|
|
171
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
172
|
+
try {
|
|
173
|
+
const isOnline = this.getOnlineStatusMonitoring().onlineStatus;
|
|
174
|
+
if (!isOnline)
|
|
175
|
+
return;
|
|
176
|
+
const activeRides = yield this.getApi().getAll();
|
|
177
|
+
const routes = this.getRouteList().getAllRoutes();
|
|
178
|
+
const counts = [];
|
|
179
|
+
routes.forEach(route => {
|
|
180
|
+
var _a;
|
|
181
|
+
const routeRides = (_a = activeRides.filter(ar => ar.ride.routeHash === route.description.routeHash)) !== null && _a !== void 0 ? _a : [];
|
|
182
|
+
const count = routeRides.length;
|
|
183
|
+
counts.push({
|
|
184
|
+
count,
|
|
185
|
+
routeId: route.description.id,
|
|
186
|
+
routeHash: route.description.routeHash
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
this.routesStats = counts;
|
|
190
|
+
return counts;
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
const isOnline = this.getOnlineStatusMonitoring().onlineStatus;
|
|
194
|
+
if (isOnline)
|
|
195
|
+
this.logError(err, 'getActiveRideCounts');
|
|
196
|
+
}
|
|
197
|
+
return [];
|
|
198
|
+
});
|
|
199
|
+
}
|
|
144
200
|
start(session) {
|
|
145
201
|
if (this.onlineStatusHandler || this.isOnline) {
|
|
146
202
|
this.initList();
|
|
@@ -501,13 +557,21 @@ let ActiveRidesService = (() => {
|
|
|
501
557
|
}
|
|
502
558
|
subscribeActivityEvents() {
|
|
503
559
|
return __awaiter(this, void 0, void 0, function* () {
|
|
504
|
-
var _a;
|
|
560
|
+
var _a, _b;
|
|
505
561
|
const hash = (_a = this.current) === null || _a === void 0 ? void 0 : _a.ride.routeHash;
|
|
506
|
-
const
|
|
507
|
-
|
|
562
|
+
const session = (_b = this.current) === null || _b === void 0 ? void 0 : _b.sessionId;
|
|
563
|
+
const updateTopic = `incyclist/activity/+/${hash}/+`;
|
|
564
|
+
this.getMessageQueue().subscribe(updateTopic, this.onActivityEvent.bind(this), 'incyclist/activity');
|
|
565
|
+
const infoTopic = `incyclist/session/${session}/info`;
|
|
566
|
+
this.getMessageQueue().subscribe(infoTopic, this.onInfoEvent.bind(this), 'incyclist/session');
|
|
508
567
|
this.isSubscribed = true;
|
|
509
568
|
});
|
|
510
569
|
}
|
|
570
|
+
onInfoEvent(topic) {
|
|
571
|
+
const keys = topic.split('/');
|
|
572
|
+
const session = keys[2];
|
|
573
|
+
this.onActivityInfoEvent(session);
|
|
574
|
+
}
|
|
511
575
|
onActivityEvent(topic, payload) {
|
|
512
576
|
const keys = topic.split('/');
|
|
513
577
|
const session = keys[2];
|
|
@@ -529,6 +593,21 @@ let ActiveRidesService = (() => {
|
|
|
529
593
|
const topic = `incyclist/activity/${this.session}/${this.getRouteHash()}/start`;
|
|
530
594
|
this.getMessageQueue().sendMessage(topic, payload);
|
|
531
595
|
}
|
|
596
|
+
onActivityInfoEvent(session) {
|
|
597
|
+
this.logEvent({ message: 'Received session info request', sessionId: session });
|
|
598
|
+
if (session !== this.current.sessionId)
|
|
599
|
+
return;
|
|
600
|
+
const payload = {
|
|
601
|
+
user: this.current.user,
|
|
602
|
+
ride: this.current.ride,
|
|
603
|
+
position: this.current.currentPosition,
|
|
604
|
+
rideDistance: this.current.currentRideDistance,
|
|
605
|
+
duration: this.current.currentDuration,
|
|
606
|
+
lap: this.current.currentLap
|
|
607
|
+
};
|
|
608
|
+
const topic = `incyclist/activity/${this.session}/${this.getRouteHash()}/info`;
|
|
609
|
+
this.getMessageQueue().sendMessage(topic, payload);
|
|
610
|
+
}
|
|
532
611
|
onActivityStartEvent(session, payload) {
|
|
533
612
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
534
613
|
const prevActive = (_a = this.others) === null || _a === void 0 ? void 0 : _a.length;
|
|
@@ -63,6 +63,11 @@ export interface ActivityUpdateMessage extends ActiveRideListMessage {
|
|
|
63
63
|
duration?: number;
|
|
64
64
|
isPaused?: boolean;
|
|
65
65
|
}
|
|
66
|
+
export interface ActivityInfoMessage extends ActivityStartMessage {
|
|
67
|
+
rideDistance: number;
|
|
68
|
+
lap?: number;
|
|
69
|
+
duration?: number;
|
|
70
|
+
}
|
|
66
71
|
export type ActiveRideListAvatar = {
|
|
67
72
|
shirt: string;
|
|
68
73
|
helmet: string;
|
|
@@ -151,6 +151,7 @@ let FreeRideDisplayService = (() => {
|
|
|
151
151
|
onTurn() {
|
|
152
152
|
return __awaiter(this, void 0, void 0, function* () {
|
|
153
153
|
var _b, _c, _d, _e;
|
|
154
|
+
this.logEvent({ message: 'initiating turn', position: this.position });
|
|
154
155
|
this.turnPosition = this.position;
|
|
155
156
|
this.isTurnEnabled = false;
|
|
156
157
|
this.tsLastTurn = Date.now();
|
|
@@ -164,16 +164,22 @@ let RouteDisplayService = (() => {
|
|
|
164
164
|
}
|
|
165
165
|
getNearbyRidesProps(props) {
|
|
166
166
|
var _b, _c;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this.hasNearbyRides
|
|
174
|
-
|
|
167
|
+
try {
|
|
168
|
+
const { minimized } = this.getOverlayProps('', props);
|
|
169
|
+
const hasNearbyRides = ((_b = this.getActiveRides().get()) === null || _b === void 0 ? void 0 : _b.length) > 0;
|
|
170
|
+
const show = hasNearbyRides && !props.hideAll;
|
|
171
|
+
const observer = (_c = this.getActiveRides().getObserver()) !== null && _c !== void 0 ? _c : null;
|
|
172
|
+
const nearbyRides = { show, minimized, observer };
|
|
173
|
+
if (this.hasNearbyRides !== hasNearbyRides) {
|
|
174
|
+
this.hasNearbyRides = hasNearbyRides;
|
|
175
|
+
this.service.getObserver().emit('overlay-update', { nearbyRides });
|
|
176
|
+
}
|
|
177
|
+
return nearbyRides;
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
this.logError(err, 'getNearbyRidesProps');
|
|
181
|
+
return { show: false, minimized: true, observer: null };
|
|
175
182
|
}
|
|
176
|
-
return nearbyRides;
|
|
177
183
|
}
|
|
178
184
|
getDisplayProperties(props) {
|
|
179
185
|
const { realityFactor, startPos, endPos } = this.startSettings;
|
|
@@ -94,26 +94,35 @@ let FreeRideService = (() => {
|
|
|
94
94
|
}
|
|
95
95
|
getNextOptions(forStart) {
|
|
96
96
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
var _a, _b;
|
|
97
|
+
var _a, _b, _c;
|
|
98
98
|
let prepared = false;
|
|
99
99
|
const from = this.selectedOption;
|
|
100
100
|
const optionsInfo = (opts) => {
|
|
101
101
|
var _a;
|
|
102
102
|
return (_a = opts === null || opts === void 0 ? void 0 : opts.map(o => this.buildId(o)).join('|')) !== null && _a !== void 0 ? _a : 'none';
|
|
103
103
|
};
|
|
104
|
+
let loadAsync = false;
|
|
104
105
|
if (((_a = from === null || from === void 0 ? void 0 : from.options) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
105
106
|
this.options = this.evaluateOptions(from.options, from);
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.length) {
|
|
108
|
+
prepared = true;
|
|
109
|
+
this.getNextLevelOptions(from.options);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
loadAsync = true;
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
|
-
|
|
115
|
+
if (loadAsync) {
|
|
110
116
|
this.options = yield this.loadNextOptions(from, forStart);
|
|
111
117
|
}
|
|
112
118
|
const message = forStart ? 'start options updated' : 'free ride options updated';
|
|
113
119
|
this.logEvent({ message, prepared, options: optionsInfo(this.options), from: this.buildId(from) });
|
|
114
|
-
if (((
|
|
120
|
+
if (((_c = this.options) === null || _c === void 0 ? void 0 : _c.length) > 0) {
|
|
115
121
|
this.selectOption(this.options[0]);
|
|
116
122
|
}
|
|
123
|
+
else {
|
|
124
|
+
this.selectedOption = undefined;
|
|
125
|
+
}
|
|
117
126
|
return this.options;
|
|
118
127
|
});
|
|
119
128
|
}
|
|
@@ -362,16 +371,17 @@ let FreeRideService = (() => {
|
|
|
362
371
|
selectOption(option) {
|
|
363
372
|
var _a;
|
|
364
373
|
const current = this.selectedOption;
|
|
374
|
+
const options = (_a = this.options) !== null && _a !== void 0 ? _a : [];
|
|
365
375
|
let opt;
|
|
366
376
|
switch (typeof option) {
|
|
367
377
|
case 'number':
|
|
368
|
-
opt =
|
|
378
|
+
opt = options[option - 1];
|
|
369
379
|
break;
|
|
370
380
|
case 'string':
|
|
371
|
-
opt =
|
|
381
|
+
opt = options.find(o => this.buildId(o) === option);
|
|
372
382
|
if (!opt) {
|
|
373
383
|
const wayId = option.split(':')[0];
|
|
374
|
-
opt =
|
|
384
|
+
opt = options.find(o => o.id === wayId);
|
|
375
385
|
}
|
|
376
386
|
if (!opt) {
|
|
377
387
|
opt = current;
|
|
@@ -380,9 +390,9 @@ let FreeRideService = (() => {
|
|
|
380
390
|
default:
|
|
381
391
|
opt = option;
|
|
382
392
|
}
|
|
383
|
-
this.selectedOption =
|
|
393
|
+
this.selectedOption = options === null || options === void 0 ? void 0 : options.find(o => this.buildId(o) === this.buildId(opt));
|
|
384
394
|
if (!this.selectedOption) {
|
|
385
|
-
this.logEvent({ message: 'free ride option selection failed', requested: option, type: typeof option, options:
|
|
395
|
+
this.logEvent({ message: 'free ride option selection failed', requested: option, type: typeof option, options: options !== null && options !== void 0 ? options : 'none', optionKeys: options.map(o => this.buildId(o)) });
|
|
386
396
|
}
|
|
387
397
|
return this.options;
|
|
388
398
|
}
|
|
@@ -20,6 +20,7 @@ export interface SummaryCardDisplayProps extends RouteInfo {
|
|
|
20
20
|
initialized: boolean;
|
|
21
21
|
loading?: boolean;
|
|
22
22
|
isNew?: boolean;
|
|
23
|
+
cntActive?: number;
|
|
23
24
|
}
|
|
24
25
|
export interface DetailCardDisplayProps {
|
|
25
26
|
}
|
|
@@ -64,6 +65,7 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
|
|
|
64
65
|
protected deleteObserver: PromiseObserver<boolean>;
|
|
65
66
|
protected ready: boolean;
|
|
66
67
|
protected logger: EventLogger;
|
|
68
|
+
protected cntActive: number;
|
|
67
69
|
constructor(route: Route, props?: {
|
|
68
70
|
list?: CardList<Route>;
|
|
69
71
|
});
|
|
@@ -86,6 +88,7 @@ export declare class RouteCard extends BaseCard implements Card<Route> {
|
|
|
86
88
|
setRouteData(details: RouteApiDetail): void;
|
|
87
89
|
getCardType(): RouteCardType;
|
|
88
90
|
getTitle(): string;
|
|
91
|
+
setActiveCount(cnt: number, update?: boolean): Promise<void>;
|
|
89
92
|
getDisplayProperties(): SummaryCardDisplayProps;
|
|
90
93
|
getMarkers(settings?: RouteSettings): Array<RoutePoint>;
|
|
91
94
|
getId(): string;
|
|
@@ -195,6 +195,17 @@ class RouteCard extends base_1.BaseCard {
|
|
|
195
195
|
getTitle() {
|
|
196
196
|
return this.route.title;
|
|
197
197
|
}
|
|
198
|
+
setActiveCount(cnt_1) {
|
|
199
|
+
return __awaiter(this, arguments, void 0, function* (cnt, update = true) {
|
|
200
|
+
var _a;
|
|
201
|
+
const prev = (_a = this.cntActive) !== null && _a !== void 0 ? _a : 0;
|
|
202
|
+
this.cntActive = cnt !== null && cnt !== void 0 ? cnt : 0;
|
|
203
|
+
if (update && prev !== this.cntActive) {
|
|
204
|
+
yield (0, utils_1.waitNextTick)();
|
|
205
|
+
this.emitUpdate();
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
}
|
|
198
209
|
getDisplayProperties() {
|
|
199
210
|
var _a;
|
|
200
211
|
try {
|
|
@@ -211,7 +222,7 @@ class RouteCard extends base_1.BaseCard {
|
|
|
211
222
|
let isNew = (0, utils_2.checkIsNew)(descr);
|
|
212
223
|
const loaded = details !== undefined;
|
|
213
224
|
const loading = this.deleteObserver !== undefined;
|
|
214
|
-
return Object.assign(Object.assign({}, descr), { initialized: this.initialized, loaded, ready: true, state: 'loaded', visible: this.visible, isNew, canDelete: this.canDelete(), points, loading, title: this.getTitle(), observer: this.cardObserver });
|
|
225
|
+
return Object.assign(Object.assign({}, descr), { initialized: this.initialized, loaded, ready: true, state: 'loaded', visible: this.visible, isNew, canDelete: this.canDelete(), points, loading, title: this.getTitle(), observer: this.cardObserver, cntActive: this.cntActive });
|
|
215
226
|
}
|
|
216
227
|
catch (err) {
|
|
217
228
|
this.logError(err, 'getDisplayProperties');
|
|
@@ -9,7 +9,7 @@ import { RouteInfo } from "../base/types";
|
|
|
9
9
|
import { RoutesApiLoader } from "./loaders/api";
|
|
10
10
|
import { MyRoutes } from "./lists/myroutes";
|
|
11
11
|
import { RouteCard, SummaryCardDisplayProps } from "./cards/RouteCard";
|
|
12
|
-
import { DisplayType, IRouteList, RouteStartSettings, SearchFilter, SearchFilterOptions } from "./types";
|
|
12
|
+
import { ActiveRideCount, DisplayType, IRouteList, RouteStartSettings, SearchFilter, SearchFilterOptions } from "./types";
|
|
13
13
|
import { RoutesDbLoader } from "./loaders/db";
|
|
14
14
|
import { RouteListObserver } from "./RouteListObserver";
|
|
15
15
|
import { ActiveImportCard } from "./cards/ActiveImportCard";
|
|
@@ -43,6 +43,7 @@ export declare class RouteListService extends IncyclistService implements IRoute
|
|
|
43
43
|
observer?: Observer;
|
|
44
44
|
};
|
|
45
45
|
protected currentView: 'list' | 'grid' | 'routes';
|
|
46
|
+
protected stats: any;
|
|
46
47
|
constructor();
|
|
47
48
|
setLanguage(language: string): void;
|
|
48
49
|
getLanguage(): string;
|
|
@@ -93,6 +94,7 @@ export declare class RouteListService extends IncyclistService implements IRoute
|
|
|
93
94
|
};
|
|
94
95
|
getVisibleRoutes(): Array<Route>;
|
|
95
96
|
getAllAppRoutes(source: string): Array<RouteInfo>;
|
|
97
|
+
getAllRoutes(): Array<Route>;
|
|
96
98
|
searchRepo(requestedFilters?: SearchFilter): {
|
|
97
99
|
routes: SummaryCardDisplayProps[];
|
|
98
100
|
filters: SearchFilter;
|
|
@@ -186,6 +188,7 @@ export declare class RouteListService extends IncyclistService implements IRoute
|
|
|
186
188
|
protected resetCards(): void;
|
|
187
189
|
protected getAllSearchCards(): RouteCard[];
|
|
188
190
|
protected handleConfigChanges(): void;
|
|
191
|
+
protected onRouteStatsUpdate(stats: ActiveRideCount[]): void;
|
|
189
192
|
protected getUserSettings(): import("../../settings").UserSettingsService;
|
|
190
193
|
protected getRouteSyncFactory(): RouteSyncFactory;
|
|
191
194
|
protected getAppState(): import("../../appstate").AppStateService;
|
|
@@ -150,6 +150,8 @@ let RouteListService = (() => {
|
|
|
150
150
|
}
|
|
151
151
|
if (this.initialized && !hasLists)
|
|
152
152
|
emitLoadedEvent();
|
|
153
|
+
this.observer.on('stats-update', this.onRouteStatsUpdate.bind(this));
|
|
154
|
+
this.emit('opened', this.observer, this.stats === undefined);
|
|
153
155
|
}
|
|
154
156
|
catch (err) {
|
|
155
157
|
this.logError(err, 'open');
|
|
@@ -174,6 +176,7 @@ let RouteListService = (() => {
|
|
|
174
176
|
var _a, _b;
|
|
175
177
|
try {
|
|
176
178
|
this.logEvent({ message: 'close route list' });
|
|
179
|
+
this.emit('closed', this.observer);
|
|
177
180
|
(_a = this.observer) === null || _a === void 0 ? void 0 : _a.emit('stopped');
|
|
178
181
|
(_b = this.observer) === null || _b === void 0 ? void 0 : _b.reset();
|
|
179
182
|
this.resetCards();
|
|
@@ -210,6 +213,8 @@ let RouteListService = (() => {
|
|
|
210
213
|
this.saveFilters(filters);
|
|
211
214
|
}
|
|
212
215
|
const res = this.searchRepo(filters);
|
|
216
|
+
this.observer.on('stats-update', this.onRouteStatsUpdate.bind(this));
|
|
217
|
+
this.emit('opened', this.observer, this.stats === undefined);
|
|
213
218
|
this.getAppState().setPersistedState('page', 'search');
|
|
214
219
|
return res;
|
|
215
220
|
}
|
|
@@ -221,9 +226,13 @@ let RouteListService = (() => {
|
|
|
221
226
|
routes = this.applySourceFilter({ routeSource: source }, routes);
|
|
222
227
|
return routes;
|
|
223
228
|
}
|
|
229
|
+
getAllRoutes() {
|
|
230
|
+
return this.routes;
|
|
231
|
+
}
|
|
224
232
|
searchRepo(requestedFilters) {
|
|
225
|
-
if (!this.observer)
|
|
233
|
+
if (!this.observer) {
|
|
226
234
|
this.observer = new RouteListObserver_1.RouteListObserver(this);
|
|
235
|
+
}
|
|
227
236
|
try {
|
|
228
237
|
const filters = requestedFilters !== null && requestedFilters !== void 0 ? requestedFilters : this.filters;
|
|
229
238
|
let routes = Array.from(this.getAllSearchCards().map(c => c.getDisplayProperties()));
|
|
@@ -1163,6 +1172,16 @@ let RouteListService = (() => {
|
|
|
1163
1172
|
this.emitLists('updated');
|
|
1164
1173
|
});
|
|
1165
1174
|
}
|
|
1175
|
+
onRouteStatsUpdate(stats) {
|
|
1176
|
+
this.stats = stats;
|
|
1177
|
+
for (const stat of stats) {
|
|
1178
|
+
const id = stat.routeId;
|
|
1179
|
+
const card = this.getCard(id);
|
|
1180
|
+
if (card) {
|
|
1181
|
+
card.setActiveCount(stat.count);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1166
1185
|
getUserSettings() {
|
|
1167
1186
|
return (0, settings_1.useUserSettings)();
|
|
1168
1187
|
}
|
|
@@ -84,6 +84,7 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
const tsStart = Date.now();
|
|
87
|
+
this.rlvPrev = Object.assign({}, this.rlvStatus);
|
|
87
88
|
this.tsStart = (_c = this.tsStart) !== null && _c !== void 0 ? _c : Date.now();
|
|
88
89
|
let updates = [];
|
|
89
90
|
if (e.bufferedTime !== undefined) {
|
|
@@ -95,6 +96,7 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
95
96
|
delete this.bufferedTimeIssue;
|
|
96
97
|
this.maxSuccessRate = 1;
|
|
97
98
|
this.maxRate = MAX_PLAYBACK_RATE;
|
|
99
|
+
this.logEvent({ message: 'video forwarded', time });
|
|
98
100
|
updates.push('rlv:time-reset');
|
|
99
101
|
}
|
|
100
102
|
else if (this.rlvStatus.timeRequested !== undefined && time < this.rlvStatus.timeRequested) {
|
|
@@ -129,13 +131,13 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
129
131
|
this.logEvent({ message: 'video rate update timeout' });
|
|
130
132
|
}
|
|
131
133
|
this.checkIfStalledEnded(time);
|
|
132
|
-
this.rlvPrev = Object.assign({}, this.rlvStatus);
|
|
133
134
|
if (this.isPaused) {
|
|
134
135
|
this.rlvStatus.ts = Date.now();
|
|
135
136
|
this.rlvStatus.time = time;
|
|
136
137
|
this.rlvStatus.rate = 0;
|
|
137
138
|
return;
|
|
138
139
|
}
|
|
140
|
+
const prevTime = this.rlvPrev.time;
|
|
139
141
|
this.rlvStatus.ts = Date.now();
|
|
140
142
|
this.rlvStatus.time = time;
|
|
141
143
|
this.rlvStatus.rate = rate;
|
|
@@ -150,10 +152,10 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
150
152
|
}
|
|
151
153
|
updates.push('rlv:lap');
|
|
152
154
|
}
|
|
153
|
-
else if (time < this.rlvStatus.time && time < 10) {
|
|
154
|
-
delete this.rlvStatus.lapRequested;
|
|
155
|
-
}
|
|
156
155
|
else {
|
|
156
|
+
if (this.rlvStatus.lapRequested && time < prevTime && time < 10) {
|
|
157
|
+
delete this.rlvStatus.lapRequested;
|
|
158
|
+
}
|
|
157
159
|
const vt = this.loopMode ? this.getLapTime(time) : (time > this.getTotalTime() ? this.getTotalTime() : time);
|
|
158
160
|
const mapping = this.getMappingByTime(vt);
|
|
159
161
|
if (mapping) {
|
|
@@ -252,14 +254,21 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
252
254
|
return updates.some(u => u.startsWith('rlv'));
|
|
253
255
|
};
|
|
254
256
|
const log = () => {
|
|
255
|
-
var _a;
|
|
257
|
+
var _a, _b;
|
|
256
258
|
if (!canLog())
|
|
257
259
|
return;
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
let debug = {};
|
|
261
|
+
if (Math.abs(delta) > 1000) {
|
|
262
|
+
const mapping = this.getMappingByTime(this.rlvStatus.time);
|
|
263
|
+
const tDelta = (Date.now() - this.rlvStatus.ts) / 1000;
|
|
264
|
+
const s0 = this.rlvStatus.routeDistance;
|
|
265
|
+
const v = this.rlvStatus.speed / 3.6 * ((_a = this.rlvStatus.rate) !== null && _a !== void 0 ? _a : 1);
|
|
266
|
+
debug = { mapping, tDelta, s0, v };
|
|
267
|
+
}
|
|
260
268
|
if (f(rlvDistance) === '-') {
|
|
261
|
-
|
|
269
|
+
debug = Object.assign(Object.assign({}, debug), { rlvStatus: this.rlvStatus, activityStatus: this.activityStatus });
|
|
262
270
|
}
|
|
271
|
+
this.logEvent(Object.assign({ message: 'video playback update', updates: updates.join('|'), delta: n(delta, 1), bufferedTime: n(this.bufferedTime, 1), rlvDistance: f(rlvDistance), actDistance: f(actDistance), rlvTime: n((_b = this.rlvStatus) === null || _b === void 0 ? void 0 : _b.time, 2), rate: n(this.rlvStatus.rate, 2), maxRate: n(this.maxRate, 2), maxSuccessRate: n(this.maxSuccessRate, 2) }, debug));
|
|
263
272
|
};
|
|
264
273
|
if (this.loopMode && actDistance > totalDistance) {
|
|
265
274
|
actDistance = actDistance % totalDistance;
|
|
@@ -282,7 +291,7 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
282
291
|
if (Math.abs(delta) > MAX_DELTA) {
|
|
283
292
|
const newTime = this.getVideoTimeByPosition(actDistance);
|
|
284
293
|
if (newTime - this.rlvStatus.time > 1) {
|
|
285
|
-
this.logEvent({ message: 'video
|
|
294
|
+
this.logEvent({ message: 'video forward requested', newTime });
|
|
286
295
|
this.updateTime(newTime);
|
|
287
296
|
this.prevDelta = delta;
|
|
288
297
|
}
|
|
@@ -355,6 +364,7 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
355
364
|
if (this.rlvStatus.timeRequested)
|
|
356
365
|
return;
|
|
357
366
|
this.rlvStatus.timeRequested = time;
|
|
367
|
+
this.rlvStatus.ts = Date.now();
|
|
358
368
|
delete this.rlvStatus.rateRequested;
|
|
359
369
|
delete this.rlvStatus.tsLastRateRequest;
|
|
360
370
|
delete this.tsLastIssue;
|
|
@@ -581,19 +591,23 @@ class VideoSyncHelper extends service_1.IncyclistService {
|
|
|
581
591
|
if (this.rlvStatus.tsVideoUpdate === undefined)
|
|
582
592
|
return;
|
|
583
593
|
const timeSinceLastUpdate = Date.now() - this.rlvStatus.tsVideoUpdate;
|
|
584
|
-
if (timeSinceLastUpdate > 2000 && !this.rlvStatus.isStalled) {
|
|
594
|
+
if (timeSinceLastUpdate > 2000 && !this.rlvStatus.isStalled && this.rlvStatus.rate > 0.1 && !this.isPaused && !this.isStopped) {
|
|
585
595
|
this.rlvStatus.isStalled = true;
|
|
596
|
+
this.rlvStatus.tsStalled = this.rlvStatus.tsVideoUpdate;
|
|
586
597
|
this.logEvent({ message: 'video stalled', time: this.rlvStatus.time, source: 'timeout' });
|
|
587
598
|
}
|
|
588
599
|
}
|
|
589
600
|
checkIfStalledEnded(time) {
|
|
601
|
+
var _a;
|
|
590
602
|
if (!this.rlvStatus.isStalled)
|
|
591
603
|
return;
|
|
592
604
|
if (!this.rlvPrev)
|
|
593
605
|
return;
|
|
594
606
|
if (time > this.rlvPrev.time) {
|
|
595
607
|
this.rlvStatus.isStalled = false;
|
|
596
|
-
|
|
608
|
+
const duration = Date.now() - ((_a = this.rlvStatus.tsStalled) !== null && _a !== void 0 ? _a : 0);
|
|
609
|
+
delete this.rlvStatus.tsStalled;
|
|
610
|
+
this.logEvent({ message: 'video playback unstalled', time: this.rlvStatus.time, duration });
|
|
597
611
|
}
|
|
598
612
|
}
|
|
599
613
|
}
|
package/lib/video/types.d.ts
CHANGED