feat: add PopupAd and AdminPopupAd interfaces with CRUD operations

- Introduced PopupAd and AdminPopupAd interfaces in common.ts.
- Implemented encoding, decoding, and JSON conversion methods for both PopupAd and AdminPopupAd.
- Added new RPC methods for managing PopupAds in admin.ts and me.ts, including list, create, update, and delete functionalities.
- Integrated PopupAdsClient in grpcClient.ts for gRPC communication.
- Updated auth store to handle real-time notifications for user-specific topics.
- Modified tsconfig.json to include auto-imports and components type definitions.
This commit is contained in:
2026-03-29 06:42:37 +00:00
parent 43702e8bf7
commit 8515498ade
31 changed files with 3905 additions and 78 deletions

View File

@@ -85,7 +85,9 @@ export class TinyMqttClient implements ITinyMqttClient {
break;
case 0xD0: // PINGRESP
break;
case 0x30: // PUBLISH
case 0x30: // PUBLISH QoS 0
case 0x32: // PUBLISH QoS 1
case 0x34: // PUBLISH QoS 2
this.parsePublish(data);
break;
}
@@ -102,9 +104,32 @@ export class TinyMqttClient implements ITinyMqttClient {
}
private parsePublish(data: Uint8Array): void {
const tLen = (data[2] << 8) | data[3];
const topic = this.decoder.decode(data.slice(4, 4 + tLen));
const payload = this.decoder.decode(data.slice(4 + tLen));
let multiplier = 1;
let remainingLength = 0;
let offset = 1;
let encodedByte = 0;
do {
encodedByte = data[offset++];
remainingLength += (encodedByte & 127) * multiplier;
multiplier *= 128;
} while ((encodedByte & 128) !== 0 && offset < data.length);
const variableHeaderStart = offset;
const topicLength = (data[offset] << 8) | data[offset + 1];
offset += 2;
const topic = this.decoder.decode(data.slice(offset, offset + topicLength));
offset += topicLength;
const qos = (data[0] >> 1) & 0x03;
if (qos > 0) {
offset += 2; // packet identifier
}
const consumedFromVariableHeader = offset - variableHeaderStart;
const payloadLength = Math.max(0, remainingLength - consumedFromVariableHeader);
const payload = this.decoder.decode(data.slice(offset, offset + payloadLength));
this.onMessage(topic, payload);
}
}