promo.gno
2.94 Kb · 85 lines
1package catalog
2
3import (
4 "gno.land/p/nym-alexiscolin000/gnoradio/store/v0"
5 "gno.land/p/nym-alexiscolin000/gnoradio/text/v0"
6 "gno.land/r/nym-alexiscolin000/gnoradio/data"
7)
8
9// Promo share: an artist lets a part of each tip go to the listeners who
10// brought the tipper, the one who picked the track on the radio and the one
11// whose link they followed. It is opt-in: 0% until the artist sets it
12// (0..20%), and the tipper sees it before signing. A tipper never pays it to
13// themselves: not as the picker, not as the referrer, and not to a
14// referrer they name for a track they picked (social.gno, tip). The radio realm alone knows who picked what
15// is on air, so the shared tips arrive through RadioTip, which only the
16// current radio writer of the data realm may call; it never takes a picker
17// from the client.
18
19const (
20 defaultPromoPct = 0
21 maxPromoPct = 20
22)
23
24// SetPromoShare sets the percent of each tip on the caller's tracks that goes
25// to the picker and the referrer (0..20).
26func SetPromoShare(cur realm, pct int) {
27 caller := userCaller(cur)
28 noPayment()
29 if pct < 0 || pct > maxPromoPct {
30 panic("catalog: the promo share is between 0 and 20%")
31 }
32 t := rd()
33 id, _ := ownArtist(t, caller)
34 t.set(cPromo, store.Pad(id), text.Itoa(pct))
35 save(cur, t)
36 emitEvent("PromoShare", "artist", text.Itoa(id), "pct", text.Itoa(pct))
37}
38
39// PromoShare returns an artist's promo percent.
40func PromoShare(artistID int) int { return promoShare(rd(), artistID) }
41
42func promoShare(t *tx, artistID int) int {
43 if v, ok := t.get(cPromo, store.Pad(artistID)); ok {
44 return text.Atoi(v)
45 }
46 return defaultPromoPct
47}
48
49// RadioTip pays a tip the radio realm received for the listener tipper
50// (radio.TipOnAir): the radio has already forwarded total ugnot to this realm
51// and names the picker of the slot on air. Only the radio writer may call it.
52// It returns what the picker and the referrer received.
53func RadioTip(cur realm, trackID, supportPct int, tipper, picker, ref address, total int64) (toPicker, toRef int64) {
54 onlyRadio(cur)
55 return tip(cur, tipper, total, trackID, supportPct, picker, ref)
56}
57
58// onlyRadio admits the radio realm the data realm names as radio writer
59// now, unless the radio role is paused: a paused radio moves no coins
60// through the catalog either.
61func onlyRadio(cur realm) {
62 if cur.Previous().PkgPath() != data.Writer("radio") {
63 panic("catalog: only the GnoRadio radio realm can call this")
64 }
65 if data.Paused("radio") {
66 panic("catalog: the radio is paused")
67 }
68}
69
70// promoShares splits an artist-side amount's promo share between the picker
71// and the referrer still eligible ("" when not): half each, the odd ugnot to
72// the picker, all of it to one alone.
73func promoShares(amt int64, pct int, picker, ref address) (toPicker, toRef int64) {
74 share := amt * int64(pct) / 100
75 switch {
76 case picker != "" && ref != "":
77 toRef = share / 2
78 return share - toRef, toRef
79 case picker != "":
80 return share, 0
81 case ref != "":
82 return 0, share
83 }
84 return 0, 0
85}