@shaxpir/duiduidui-models 1.6.16 → 1.6.18

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.
@@ -16,6 +16,7 @@ export interface WorkspacePayload {
16
16
  [key: string]: CompactDateTime;
17
17
  };
18
18
  global_conditions: ConditionFilters;
19
+ uploaded_avatars: ContentId[];
19
20
  }
20
21
  export interface WorkspaceBody extends ContentBody {
21
22
  meta: ContentMeta;
@@ -24,6 +25,7 @@ export interface WorkspaceBody extends ContentBody {
24
25
  export declare class Workspace extends Content {
25
26
  private _devicesView;
26
27
  private _sessionsView;
28
+ private _uploadedAvatarsView;
27
29
  constructor(doc: Doc, shouldAcquire: boolean, shareSync: ShareSync);
28
30
  get payload(): WorkspacePayload;
29
31
  getGlobalConditions(): ConditionFilters;
@@ -31,6 +33,7 @@ export declare class Workspace extends Content {
31
33
  static create(userId: ContentId, payload: WorkspacePayload): Workspace;
32
34
  get sessions(): ArrayView<MultiTime>;
33
35
  get devices(): ArrayView<ContentId>;
36
+ get uploadedAvatars(): ArrayView<ContentId>;
34
37
  acquireSessionForUtcTime(utcTime: CompactDateTime): Promise<Session | null>;
35
38
  acquireSessionsFromDate(localDate: CompactDate): Promise<Session[]>;
36
39
  hasJourneyDate(journeyKey: string): boolean;
@@ -13,6 +13,7 @@ class Workspace extends Content_1.Content {
13
13
  super(doc, shouldAcquire, shareSync);
14
14
  this._devicesView = new ArrayView_1.ArrayView(this, ['payload', 'devices']);
15
15
  this._sessionsView = new ArrayView_1.ArrayView(this, ['payload', 'sessions']);
16
+ this._uploadedAvatarsView = new ArrayView_1.ArrayView(this, ['payload', 'uploaded_avatars']);
16
17
  }
17
18
  get payload() {
18
19
  return this.doc.data.payload;
@@ -49,6 +50,10 @@ class Workspace extends Content_1.Content {
49
50
  this.checkDisposed("Workspace.devices");
50
51
  return this._devicesView;
51
52
  }
53
+ get uploadedAvatars() {
54
+ this.checkDisposed("Workspace.uploadedAvatars");
55
+ return this._uploadedAvatarsView;
56
+ }
52
57
  async acquireSessionForUtcTime(utcTime) {
53
58
  this.checkDisposed("Workspace.acquireSessionForUtcTime");
54
59
  const shareSync = repo_1.ShareSyncFactory.get();
@@ -44,6 +44,10 @@ export declare class ShareSync {
44
44
  private _socket;
45
45
  private _connection;
46
46
  private _listener;
47
+ private _onSocketOpen;
48
+ private _onSocketMessage;
49
+ private _onSocketClose;
50
+ private _onSocketError;
47
51
  private _storage;
48
52
  private _durableStore;
49
53
  private _storageFactory?;
@@ -96,26 +96,31 @@ class ShareSync {
96
96
  shareSync._socket = new reconnecting_websocket_1.default(options.urlProvider);
97
97
  }
98
98
  function updateSocketIsOpen() {
99
- shareSync._socketIsOpen = shareSync._socket.readyState === reconnecting_websocket_1.default.OPEN;
99
+ shareSync._socketIsOpen = shareSync._socket ? shareSync._socket.readyState === reconnecting_websocket_1.default.OPEN : false;
100
100
  }
101
101
  // The listener should forward all events: open, message, close, error
102
102
  shareSync._listener = options.connectionListener;
103
- shareSync._socket.addEventListener('open', (event) => {
103
+ // Store event handlers as instance variables so we can remove them during shutdown
104
+ shareSync._onSocketOpen = (event) => {
104
105
  updateSocketIsOpen();
105
106
  shareSync._listener.onSocketEvent('open', event);
106
- });
107
- shareSync._socket.addEventListener('message', (event) => {
107
+ };
108
+ shareSync._onSocketMessage = (event) => {
108
109
  updateSocketIsOpen();
109
110
  shareSync._listener.onSocketEvent('message', event);
110
- });
111
- shareSync._socket.addEventListener('close', (event) => {
111
+ };
112
+ shareSync._onSocketClose = (event) => {
112
113
  updateSocketIsOpen();
113
114
  shareSync._listener.onSocketEvent('close', event);
114
- });
115
- shareSync._socket.addEventListener('error', (event) => {
115
+ };
116
+ shareSync._onSocketError = (event) => {
116
117
  updateSocketIsOpen();
117
118
  shareSync._listener.onSocketEvent('error', event);
118
- });
119
+ };
120
+ shareSync._socket.addEventListener('open', shareSync._onSocketOpen);
121
+ shareSync._socket.addEventListener('message', shareSync._onSocketMessage);
122
+ shareSync._socket.addEventListener('close', shareSync._onSocketClose);
123
+ shareSync._socket.addEventListener('error', shareSync._onSocketError);
119
124
  // Initialize DurableStore first if enabled, then create connection with it
120
125
  if (shareSync._hasDurableStore) {
121
126
  shareSync.initializeDurableStore(options).then(() => {
@@ -472,8 +477,20 @@ class ShareSync {
472
477
  }
473
478
  shutdown() {
474
479
  console.log('[ShareSync] Shutting down...');
475
- // Close the WebSocket connection
480
+ // Remove event listeners before closing the socket to prevent handlers from firing during shutdown
476
481
  if (this._socket) {
482
+ if (this._onSocketOpen) {
483
+ this._socket.removeEventListener('open', this._onSocketOpen);
484
+ }
485
+ if (this._onSocketMessage) {
486
+ this._socket.removeEventListener('message', this._onSocketMessage);
487
+ }
488
+ if (this._onSocketClose) {
489
+ this._socket.removeEventListener('close', this._onSocketClose);
490
+ }
491
+ if (this._onSocketError) {
492
+ this._socket.removeEventListener('error', this._onSocketError);
493
+ }
477
494
  this._socket.close();
478
495
  this._socket = null;
479
496
  }
@@ -0,0 +1,72 @@
1
+ import { ContentId } from '../models/Content';
2
+ /**
3
+ * Zodiac animals in the Chinese zodiac cycle
4
+ */
5
+ export declare enum ZodiacAnimal {
6
+ RAT = "rat",
7
+ OX = "ox",
8
+ TIGER = "tiger",
9
+ RABBIT = "rabbit",
10
+ DRAGON = "dragon",
11
+ SNAKE = "snake",
12
+ HORSE = "horse",
13
+ GOAT = "goat",
14
+ MONKEY = "monkey",
15
+ ROOSTER = "rooster",
16
+ DOG = "dog",
17
+ PIG = "pig"
18
+ }
19
+ /**
20
+ * Zodiac animal names in English and Chinese
21
+ */
22
+ export declare const ZODIAC_NAMES: Record<ZodiacAnimal, {
23
+ english: string;
24
+ chinese: string;
25
+ }>;
26
+ /**
27
+ * Get all zodiac animals in order
28
+ */
29
+ export declare function getAllZodiacAnimals(): ZodiacAnimal[];
30
+ /**
31
+ * Calculate zodiac animal from birth year
32
+ */
33
+ export declare function getZodiacAnimalFromYear(year: number): ZodiacAnimal;
34
+ /**
35
+ * Avatar URI types
36
+ */
37
+ export declare enum AvatarUriType {
38
+ ZODIAC = "zodiac",
39
+ IMAGE = "image"
40
+ }
41
+ /**
42
+ * Create a zodiac avatar URI
43
+ */
44
+ export declare function createZodiacAvatarUri(animal: ZodiacAnimal): string;
45
+ /**
46
+ * Create an image avatar URI from a ContentId
47
+ */
48
+ export declare function createImageAvatarUri(imageId: ContentId): string;
49
+ /**
50
+ * Parse an avatar URI
51
+ */
52
+ export interface ParsedAvatarUri {
53
+ type: AvatarUriType;
54
+ value: string;
55
+ }
56
+ export declare function parseAvatarUri(uri: string | ContentId | null): ParsedAvatarUri | null;
57
+ /**
58
+ * Check if a URI is a zodiac avatar
59
+ */
60
+ export declare function isZodiacAvatar(uri: string | ContentId | null): boolean;
61
+ /**
62
+ * Check if a URI is an image avatar
63
+ */
64
+ export declare function isImageAvatar(uri: string | ContentId | null): boolean;
65
+ /**
66
+ * Get zodiac animal from avatar URI (returns null if not a zodiac avatar)
67
+ */
68
+ export declare function getZodiacAnimalFromUri(uri: string | ContentId | null): ZodiacAnimal | null;
69
+ /**
70
+ * Get image ContentId from avatar URI (returns null if not an image avatar)
71
+ */
72
+ export declare function getImageIdFromUri(uri: string | ContentId | null): ContentId | null;
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AvatarUriType = exports.ZODIAC_NAMES = exports.ZodiacAnimal = void 0;
4
+ exports.getAllZodiacAnimals = getAllZodiacAnimals;
5
+ exports.getZodiacAnimalFromYear = getZodiacAnimalFromYear;
6
+ exports.createZodiacAvatarUri = createZodiacAvatarUri;
7
+ exports.createImageAvatarUri = createImageAvatarUri;
8
+ exports.parseAvatarUri = parseAvatarUri;
9
+ exports.isZodiacAvatar = isZodiacAvatar;
10
+ exports.isImageAvatar = isImageAvatar;
11
+ exports.getZodiacAnimalFromUri = getZodiacAnimalFromUri;
12
+ exports.getImageIdFromUri = getImageIdFromUri;
13
+ /**
14
+ * Zodiac animals in the Chinese zodiac cycle
15
+ */
16
+ var ZodiacAnimal;
17
+ (function (ZodiacAnimal) {
18
+ ZodiacAnimal["RAT"] = "rat";
19
+ ZodiacAnimal["OX"] = "ox";
20
+ ZodiacAnimal["TIGER"] = "tiger";
21
+ ZodiacAnimal["RABBIT"] = "rabbit";
22
+ ZodiacAnimal["DRAGON"] = "dragon";
23
+ ZodiacAnimal["SNAKE"] = "snake";
24
+ ZodiacAnimal["HORSE"] = "horse";
25
+ ZodiacAnimal["GOAT"] = "goat";
26
+ ZodiacAnimal["MONKEY"] = "monkey";
27
+ ZodiacAnimal["ROOSTER"] = "rooster";
28
+ ZodiacAnimal["DOG"] = "dog";
29
+ ZodiacAnimal["PIG"] = "pig";
30
+ })(ZodiacAnimal || (exports.ZodiacAnimal = ZodiacAnimal = {}));
31
+ /**
32
+ * Zodiac animal names in English and Chinese
33
+ */
34
+ exports.ZODIAC_NAMES = {
35
+ [ZodiacAnimal.RAT]: { english: 'Rat', chinese: '鼠' },
36
+ [ZodiacAnimal.OX]: { english: 'Ox', chinese: '牛' },
37
+ [ZodiacAnimal.TIGER]: { english: 'Tiger', chinese: '虎' },
38
+ [ZodiacAnimal.RABBIT]: { english: 'Rabbit', chinese: '兔' },
39
+ [ZodiacAnimal.DRAGON]: { english: 'Dragon', chinese: '龙' },
40
+ [ZodiacAnimal.SNAKE]: { english: 'Snake', chinese: '蛇' },
41
+ [ZodiacAnimal.HORSE]: { english: 'Horse', chinese: '马' },
42
+ [ZodiacAnimal.GOAT]: { english: 'Goat', chinese: '羊' },
43
+ [ZodiacAnimal.MONKEY]: { english: 'Monkey', chinese: '猴' },
44
+ [ZodiacAnimal.ROOSTER]: { english: 'Rooster', chinese: '鸡' },
45
+ [ZodiacAnimal.DOG]: { english: 'Dog', chinese: '狗' },
46
+ [ZodiacAnimal.PIG]: { english: 'Pig', chinese: '猪' }
47
+ };
48
+ /**
49
+ * Get all zodiac animals in order
50
+ */
51
+ function getAllZodiacAnimals() {
52
+ return [
53
+ ZodiacAnimal.RAT,
54
+ ZodiacAnimal.OX,
55
+ ZodiacAnimal.TIGER,
56
+ ZodiacAnimal.RABBIT,
57
+ ZodiacAnimal.DRAGON,
58
+ ZodiacAnimal.SNAKE,
59
+ ZodiacAnimal.HORSE,
60
+ ZodiacAnimal.GOAT,
61
+ ZodiacAnimal.MONKEY,
62
+ ZodiacAnimal.ROOSTER,
63
+ ZodiacAnimal.DOG,
64
+ ZodiacAnimal.PIG
65
+ ];
66
+ }
67
+ /**
68
+ * Calculate zodiac animal from birth year
69
+ */
70
+ function getZodiacAnimalFromYear(year) {
71
+ const animals = getAllZodiacAnimals();
72
+ // The Chinese zodiac follows a 12-year cycle starting from Rat
73
+ // 1924, 1936, 1948, 1960, 1972, 1984, 1996, 2008, 2020 are Rat years
74
+ const index = (year - 4) % 12;
75
+ return animals[index];
76
+ }
77
+ /**
78
+ * Avatar URI types
79
+ */
80
+ var AvatarUriType;
81
+ (function (AvatarUriType) {
82
+ AvatarUriType["ZODIAC"] = "zodiac";
83
+ AvatarUriType["IMAGE"] = "image";
84
+ })(AvatarUriType || (exports.AvatarUriType = AvatarUriType = {}));
85
+ /**
86
+ * Create a zodiac avatar URI
87
+ */
88
+ function createZodiacAvatarUri(animal) {
89
+ return `duiduidui://${AvatarUriType.ZODIAC}/${animal}`;
90
+ }
91
+ /**
92
+ * Create an image avatar URI from a ContentId
93
+ */
94
+ function createImageAvatarUri(imageId) {
95
+ return `duiduidui://${AvatarUriType.IMAGE}/${imageId}`;
96
+ }
97
+ function parseAvatarUri(uri) {
98
+ if (!uri) {
99
+ return null;
100
+ }
101
+ // Check if it's a duiduidui:// URI
102
+ if (uri.startsWith('duiduidui://')) {
103
+ const parts = uri.substring('duiduidui://'.length).split('/');
104
+ if (parts.length >= 2) {
105
+ const type = parts[0];
106
+ const value = parts.slice(1).join('/');
107
+ return { type, value };
108
+ }
109
+ }
110
+ // Backward compatibility: if it's not a URI, treat it as a ContentId (image)
111
+ return {
112
+ type: AvatarUriType.IMAGE,
113
+ value: uri
114
+ };
115
+ }
116
+ /**
117
+ * Check if a URI is a zodiac avatar
118
+ */
119
+ function isZodiacAvatar(uri) {
120
+ const parsed = parseAvatarUri(uri);
121
+ return parsed?.type === AvatarUriType.ZODIAC;
122
+ }
123
+ /**
124
+ * Check if a URI is an image avatar
125
+ */
126
+ function isImageAvatar(uri) {
127
+ const parsed = parseAvatarUri(uri);
128
+ return parsed?.type === AvatarUriType.IMAGE;
129
+ }
130
+ /**
131
+ * Get zodiac animal from avatar URI (returns null if not a zodiac avatar)
132
+ */
133
+ function getZodiacAnimalFromUri(uri) {
134
+ const parsed = parseAvatarUri(uri);
135
+ if (parsed?.type === AvatarUriType.ZODIAC) {
136
+ return parsed.value;
137
+ }
138
+ return null;
139
+ }
140
+ /**
141
+ * Get image ContentId from avatar URI (returns null if not an image avatar)
142
+ */
143
+ function getImageIdFromUri(uri) {
144
+ const parsed = parseAvatarUri(uri);
145
+ if (parsed?.type === AvatarUriType.IMAGE) {
146
+ return parsed.value;
147
+ }
148
+ return null;
149
+ }
@@ -1,2 +1,3 @@
1
+ export * from './AvatarUri';
1
2
  export * from './Encryption';
2
3
  export * from './Logging';
@@ -15,5 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
16
  };
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
+ __exportStar(require("./AvatarUri"), exports);
18
19
  __exportStar(require("./Encryption"), exports);
19
20
  __exportStar(require("./Logging"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shaxpir/duiduidui-models",
3
- "version": "1.6.16",
3
+ "version": "1.6.18",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/shaxpir/duiduidui-models"
@@ -21,6 +21,7 @@
21
21
  "@shaxpir/shaxpir-common": "1.4.0",
22
22
  "ot-json1": "1.0.1",
23
23
  "ot-text-unicode": "4.0.0",
24
+ "react-native-popover-view": "^6.1.0",
24
25
  "reconnecting-websocket": "4.4.0"
25
26
  },
26
27
  "devDependencies": {