feat(banner): per-campaign colour overrides and urgent alerts
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m50s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 10s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m50s
Non-default campaigns gain an optional colour override (background / text / link) in two sets — one for every theme, one for the dark theme only — and an "urgent" flag. - Colours ride profile.get as six trailing FlatBuffers strings on BannerCampaign (backward-compatible). The client resolves the cascade (dark <- dark ?? all, light <- all) per rendered theme and derives the strip border from the background in JS (no CSS color-mix, for the old Android WebView floor); AdBanner applies them as inline vars scoped to the strip. - Urgent is resolved entirely server-side: while any enabled, in-window urgent campaign exists, computeActiveSet returns only the urgent campaigns and bannerFor skips the eligibility gate — so a system notice reaches every viewer (paid / hint-holding / no_banner included) and preempts the ordinary feed. No wire field; it appears on each viewer's next profile.get. - Admin console (/_gm/banners): native colour pickers + a live light/dark preview of the strip, and an urgent toggle. The default campaign stays plain, enforced by the service and a DB CHECK. Migration 00009 is additive (nullable colour columns + a bool default + all-or-nothing / hex / default-plain CHECKs) — expand-contract, rollback-safe. Docs: ARCHITECTURE §10, UI_DESIGN, FUNCTIONAL (+ru). Tests: ads unit (urgent preempt + colour validation), codec + resolver unit, gateway transcode, and integration (colour round-trip + urgent bypass against real Postgres).
This commit is contained in:
@@ -37,8 +37,50 @@ messagesLength():number {
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
overrideBg():string|null
|
||||
overrideBg(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
overrideBg(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
overrideFg():string|null
|
||||
overrideFg(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
overrideFg(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
overrideLink():string|null
|
||||
overrideLink(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
overrideLink(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
overrideBgDark():string|null
|
||||
overrideBgDark(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
overrideBgDark(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
overrideFgDark():string|null
|
||||
overrideFgDark(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
overrideFgDark(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
overrideLinkDark():string|null
|
||||
overrideLinkDark(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
overrideLinkDark(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startBannerCampaign(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
builder.startObject(8);
|
||||
}
|
||||
|
||||
static addWeight(builder:flatbuffers.Builder, weight:number) {
|
||||
@@ -61,15 +103,45 @@ static startMessagesVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static addOverrideBg(builder:flatbuffers.Builder, overrideBgOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, overrideBgOffset, 0);
|
||||
}
|
||||
|
||||
static addOverrideFg(builder:flatbuffers.Builder, overrideFgOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, overrideFgOffset, 0);
|
||||
}
|
||||
|
||||
static addOverrideLink(builder:flatbuffers.Builder, overrideLinkOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(4, overrideLinkOffset, 0);
|
||||
}
|
||||
|
||||
static addOverrideBgDark(builder:flatbuffers.Builder, overrideBgDarkOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(5, overrideBgDarkOffset, 0);
|
||||
}
|
||||
|
||||
static addOverrideFgDark(builder:flatbuffers.Builder, overrideFgDarkOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(6, overrideFgDarkOffset, 0);
|
||||
}
|
||||
|
||||
static addOverrideLinkDark(builder:flatbuffers.Builder, overrideLinkDarkOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(7, overrideLinkDarkOffset, 0);
|
||||
}
|
||||
|
||||
static endBannerCampaign(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createBannerCampaign(builder:flatbuffers.Builder, weight:number, messagesOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
static createBannerCampaign(builder:flatbuffers.Builder, weight:number, messagesOffset:flatbuffers.Offset, overrideBgOffset:flatbuffers.Offset, overrideFgOffset:flatbuffers.Offset, overrideLinkOffset:flatbuffers.Offset, overrideBgDarkOffset:flatbuffers.Offset, overrideFgDarkOffset:flatbuffers.Offset, overrideLinkDarkOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
BannerCampaign.startBannerCampaign(builder);
|
||||
BannerCampaign.addWeight(builder, weight);
|
||||
BannerCampaign.addMessages(builder, messagesOffset);
|
||||
BannerCampaign.addOverrideBg(builder, overrideBgOffset);
|
||||
BannerCampaign.addOverrideFg(builder, overrideFgOffset);
|
||||
BannerCampaign.addOverrideLink(builder, overrideLinkOffset);
|
||||
BannerCampaign.addOverrideBgDark(builder, overrideBgDarkOffset);
|
||||
BannerCampaign.addOverrideFgDark(builder, overrideFgDarkOffset);
|
||||
BannerCampaign.addOverrideLinkDark(builder, overrideLinkDarkOffset);
|
||||
return BannerCampaign.endBannerCampaign(builder);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user