added DM support, mostly working
This commit is contained in:
parent
6c1a11706f
commit
918719599f
4
go.mod
4
go.mod
|
@ -3,9 +3,9 @@ module github.com/diamondburned/cchat-discord
|
|||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/diamondburned/arikawa v1.3.6
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201220032235-088b30430377
|
||||
github.com/diamondburned/cchat v0.3.15
|
||||
github.com/diamondburned/ningen v0.2.1-0.20201023061015-ce64ffb0bb12
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201220054153-c69c4f7057b4
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/go-test/deep v1.0.7
|
||||
github.com/lithammer/fuzzysearch v1.1.1
|
||||
|
|
42
go.sum
42
go.sum
|
@ -42,9 +42,25 @@ github.com/diamondburned/arikawa v1.2.0 h1:3dFmpk/G4UwO+Kto0tXd5AbaCKC9KH2ZfnA8U
|
|||
github.com/diamondburned/arikawa v1.2.0/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660=
|
||||
github.com/diamondburned/arikawa v1.3.0 h1:up5q5Ya/QbiFqhMejvl+c03YdsgzkzspsJOWW30A2lk=
|
||||
github.com/diamondburned/arikawa v1.3.0/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660=
|
||||
github.com/diamondburned/arikawa v1.3.2 h1:ftWgP95IJGXNvCvtO5x0QBYsnFSnIBY0SvDdGoC3ILA=
|
||||
github.com/diamondburned/arikawa v1.3.2/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660=
|
||||
github.com/diamondburned/arikawa v1.3.6 h1:DhxWDO4fyXAZ4VFrWdJOqiiJKJRpkrehGJwPtZ2eos0=
|
||||
github.com/diamondburned/arikawa v1.3.6/go.mod h1:nIhVIatzTQhPUa7NB8w4koG1RF9gYbpAr8Fj8sKq660=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201208195035-9911a3d6627a/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201218230021-9df396bb7f14 h1:2+j49uXPC44gEFstt0hlY17Wz88HU7DXgOmQmgIf28E=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201218230021-9df396bb7f14/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219061804-88911a7d1117 h1:n769tNSjYU2EDCkM3PBLTaB0LQwN9Sr3Rab9KXVxhoc=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219061804-88911a7d1117/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219063311-c9dd51aeb654 h1:z4/LcUUQ/B7l3+G1fh16/ByW206/oueKLANdygetEyA=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219063311-c9dd51aeb654/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219065126-f11edb7260b2 h1:73ukkYNYZztR3wUXzeyza6AG4zBZjA8ER6qO0QGZPPA=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219065126-f11edb7260b2/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219075756-36c2f166becd h1:HCaw0YrlQWKTao7QE6s8tjYImZEpH7Lad85bnYel1V0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201219075756-36c2f166becd/go.mod h1:/vapSS3yfYRAt5hhgI6JiPkca+wKhgi0MdanT1dBBQY=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201220000828-3e2814748f9a h1:aA8K3+JfXdJPcK9Ms4WmHLGp+qnKT0VuNWOUZUP9YpY=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201220000828-3e2814748f9a/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201220032235-088b30430377 h1:71BLnECSl0/Ns7iZmEm7MpE5+qSuWw/BQBQY2XCUmVc=
|
||||
github.com/diamondburned/arikawa/v2 v2.0.0-20201220032235-088b30430377/go.mod h1:e+lhS20ni2luFEU06Pc8paCxgZL99/RZb77dOC82CF0=
|
||||
github.com/diamondburned/cchat v0.0.34 h1:BGiVxMRA9dmW3rLilIldBvjVan7eTTpaWCCfX9IKBYU=
|
||||
github.com/diamondburned/cchat v0.0.34/go.mod h1:+zXktogE45A0om4fT6B/z6Ii7FXNafjxsNspI0rlhbU=
|
||||
github.com/diamondburned/cchat v0.0.35 h1:WiMGl8BQJgbP9E4xRxgLGlqUsHpTcJgDKDt8/6a7lBk=
|
||||
|
@ -163,6 +179,24 @@ github.com/diamondburned/ningen v0.1.1-0.20200820222640-35796f938a58 h1:sQvq5Dgm
|
|||
github.com/diamondburned/ningen v0.1.1-0.20200820222640-35796f938a58/go.mod h1:aXm69MB+Qu04OjBiixQw28zRijDc49vruMJMaHZ2c0Q=
|
||||
github.com/diamondburned/ningen v0.2.1-0.20201023061015-ce64ffb0bb12 h1:hcabAq2jPmEhrfSRrl2hHkpQXtPTIh7L58fvCxBO/C4=
|
||||
github.com/diamondburned/ningen v0.2.1-0.20201023061015-ce64ffb0bb12/go.mod h1:TcvJV0bK4bp7t+7m29/Tz9dCqgA0sJBKM/Igt0WkvT4=
|
||||
github.com/diamondburned/ningen v1.0.0 h1:fr+7oDWA0Db73CuVeLY8SScWdW6ft/aWwkULXD0flKw=
|
||||
github.com/diamondburned/ningen v1.0.0/go.mod h1:TcvJV0bK4bp7t+7m29/Tz9dCqgA0sJBKM/Igt0WkvT4=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201210080809-a14408097980 h1:g/ndgdW9sdL2KEIORhbRafnwreDksZVTPQtRF3SgriU=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201210080809-a14408097980/go.mod h1:ub/rJpU3cD1Izpa1g+JDuzmtbfP/grV2ZSK5GzL94nc=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219070301-15610044db9a h1:w8CWPYiwH9p2XGlHHeTqRWx7e8CJJLN8i4orAkOa27Y=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219070301-15610044db9a/go.mod h1:Pw4ZPQmZUonCytlKhHgan98CZeCQ4AWh0DWqvnhsuNE=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219225720-58beeea47f6d h1:2DWG8srhOrOJDffCk37L66p5yLJssY5wGdt7OPd7Y68=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219225720-58beeea47f6d/go.mod h1:9ZWVTlDzwR0/tGFrBF6iiQV8qPXlJSKsIqRIRyXtDDU=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219233304-7023c9c95229 h1:Or3Qy+gwKeIECMv2S9rWsF3xRy90kpHKgCgmixG7ybE=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219233304-7023c9c95229/go.mod h1:9ZWVTlDzwR0/tGFrBF6iiQV8qPXlJSKsIqRIRyXtDDU=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219234158-543154247f29 h1:rwyTYHlPHSO8dAAqgeSIaXLQLPlX1NC8Ebd1py1JTVg=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219234158-543154247f29/go.mod h1:9ZWVTlDzwR0/tGFrBF6iiQV8qPXlJSKsIqRIRyXtDDU=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219235002-2c75ebf8f5fc h1:cV3WgIGTNeh8MFqRRgcxjgjTLBrU/1h24jVEeA2qySg=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201219235002-2c75ebf8f5fc/go.mod h1:9ZWVTlDzwR0/tGFrBF6iiQV8qPXlJSKsIqRIRyXtDDU=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201220032656-1096439b9379 h1:gcmMWHBtgJD+HVDQqSoy1C5L4g1CVSYadwrdeYgVL30=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201220032656-1096439b9379/go.mod h1:2ZjyeHqO9jCdlfmJhhVhk8eCumx418n39uVaC/LgEgY=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201220054153-c69c4f7057b4 h1:qzh5ghfgvUllilOhkrGP29IGQT6DGfcc3lhk9uSA6nU=
|
||||
github.com/diamondburned/ningen/v2 v2.0.0-20201220054153-c69c4f7057b4/go.mod h1:2ZjyeHqO9jCdlfmJhhVhk8eCumx418n39uVaC/LgEgY=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
|
@ -199,6 +233,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
|||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY=
|
||||
github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc=
|
||||
github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
|
@ -206,6 +242,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kawasin73/umutex v0.2.1 h1:Onkzz3LKs1HThskVwdhhBocqdRQqwCZ03quDJzuPzPo=
|
||||
github.com/kawasin73/umutex v0.2.1/go.mod h1:A02N2muKVFMvFlp5c+hBycgdH964YtieGs+7mYB16NU=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
@ -237,6 +275,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -300,6 +339,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -309,6 +349,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
|
|||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package authenticate
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/api"
|
||||
"github.com/diamondburned/arikawa/v2/api"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/session"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package authenticate
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/api"
|
||||
"github.com/diamondburned/arikawa/v2/api"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/session"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
|
|
@ -3,7 +3,7 @@ package category
|
|||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
package channel
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -29,9 +33,11 @@ func New(s *state.Instance, ch discord.Channel) (cchat.Server, error) {
|
|||
|
||||
func NewChannel(s *state.Instance, ch discord.Channel) (Channel, error) {
|
||||
// Ensure the state keeps the channel's permission.
|
||||
_, err := s.Permissions(ch.ID, s.UserID)
|
||||
if err != nil {
|
||||
return Channel{}, errors.Wrap(err, "Failed to get permission")
|
||||
if ch.GuildID.IsValid() {
|
||||
_, err := s.Permissions(ch.ID, s.UserID)
|
||||
if err != nil {
|
||||
return Channel{}, errors.Wrap(err, "failed to get permission")
|
||||
}
|
||||
}
|
||||
|
||||
sharedCh := shared.Channel{
|
||||
|
@ -56,11 +62,7 @@ func (ch Channel) Name() text.Rich {
|
|||
return text.Rich{Content: ch.ID()}
|
||||
}
|
||||
|
||||
if c.NSFW {
|
||||
return text.Rich{Content: "#" + c.Name + " (nsfw)"}
|
||||
} else {
|
||||
return text.Rich{Content: "#" + c.Name}
|
||||
}
|
||||
return text.Plain(shared.ChannelName(*c))
|
||||
}
|
||||
|
||||
func (ch Channel) AsCommander() cchat.Commander {
|
||||
|
@ -74,3 +76,52 @@ func (ch Channel) AsMessenger() cchat.Messenger {
|
|||
|
||||
return message.New(ch.Channel)
|
||||
}
|
||||
|
||||
func (ch Channel) AsIconer() cchat.Iconer {
|
||||
// Guild channels never have an icon.
|
||||
if ch.GuildID.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := ch.Self()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Only DM channels should have an icon.
|
||||
if c.Type != discord.DirectMessage {
|
||||
return nil
|
||||
}
|
||||
|
||||
return PresenceAvatar{
|
||||
user: c.DMRecipients[0],
|
||||
guild: ch.GuildID,
|
||||
state: ch.State,
|
||||
}
|
||||
}
|
||||
|
||||
type PresenceAvatar struct {
|
||||
user discord.User
|
||||
guild discord.GuildID
|
||||
state *state.Instance
|
||||
}
|
||||
|
||||
func (avy PresenceAvatar) Icon(ctx context.Context, iconer cchat.IconContainer) (func(), error) {
|
||||
if avy.user.Avatar != "" {
|
||||
iconer.SetIcon(urlutils.AvatarURL(avy.user.AvatarURL()))
|
||||
}
|
||||
|
||||
// There are so many other places that could be checked, but this is good
|
||||
// enough.
|
||||
|
||||
c, err := avy.state.Presence(avy.guild, avy.user.ID)
|
||||
if err == nil && c.User.Avatar != "" {
|
||||
iconer.SetIcon(urlutils.AvatarURL(c.User.AvatarURL()))
|
||||
}
|
||||
|
||||
return avy.state.AddHandler(func(update *gateway.PresenceUpdateEvent) {
|
||||
if avy.user.ID == update.User.ID {
|
||||
iconer.SetIcon(urlutils.AvatarURL(update.User.AvatarURL()))
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@ import (
|
|||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/bot/extras/arguments"
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/bot/extras/arguments"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package action
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -43,13 +43,13 @@ func (ac Actioner) Actions(id string) []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
m, err := ac.State.Store.Message(ac.ID, discord.MessageID(s))
|
||||
m, err := ac.State.Cabinet.Message(ac.ID, discord.MessageID(s))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the current user.
|
||||
u, err := ac.State.Store.Me()
|
||||
u, err := ac.State.Cabinet.Me()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ func (ac Actioner) canManageMessages(userID discord.UserID) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
m, err := ac.State.Store.Member(ac.GuildID, userID)
|
||||
m, err := ac.State.Cabinet.Member(ac.GuildID, userID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package backlog
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/message"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package edit
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -23,7 +23,7 @@ func (ed Editor) IsEditable(id string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
m, err := ed.State.Store.Message(ed.ID, discord.MessageID(s))
|
||||
m, err := ed.State.Cabinet.Message(ed.ID, discord.MessageID(s))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (ed Editor) RawContent(id string) (string, error) {
|
|||
return "", errors.Wrap(err, "Failed to parse ID")
|
||||
}
|
||||
|
||||
m, err := ed.State.Store.Message(ed.ID, discord.MessageID(s))
|
||||
m, err := ed.State.Cabinet.Message(ed.ID, discord.MessageID(s))
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Failed to get the message")
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package indicate
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/typer"
|
||||
|
|
|
@ -3,7 +3,7 @@ package indicate
|
|||
import (
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/ningen/states/read"
|
||||
"github.com/diamondburned/ningen/v2/states/read"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
||||
|
@ -36,12 +36,12 @@ func (l *Member) ID() cchat.ID {
|
|||
}
|
||||
|
||||
func (l *Member) Name() text.Rich {
|
||||
g, err := l.channel.State.Store.Guild(l.channel.GuildID)
|
||||
g, err := l.channel.State.Cabinet.Guild(l.channel.GuildID)
|
||||
if err != nil {
|
||||
return text.Plain(l.origName)
|
||||
}
|
||||
|
||||
m, err := l.channel.State.Store.Member(l.channel.GuildID, l.userID)
|
||||
m, err := l.channel.State.Cabinet.Member(l.channel.GuildID, l.userID)
|
||||
if err != nil {
|
||||
return text.Plain(l.origName)
|
||||
}
|
||||
|
@ -80,19 +80,19 @@ func (l *Member) Icon(ctx context.Context, c cchat.IconContainer) (func(), error
|
|||
}
|
||||
|
||||
func (l *Member) Status() cchat.Status {
|
||||
p, err := l.channel.State.Store.Presence(l.channel.GuildID, l.userID)
|
||||
p, err := l.channel.State.Cabinet.Presence(l.channel.GuildID, l.userID)
|
||||
if err != nil {
|
||||
return cchat.StatusUnknown
|
||||
}
|
||||
|
||||
switch p.Status {
|
||||
case discord.OnlineStatus:
|
||||
case gateway.OnlineStatus:
|
||||
return cchat.StatusOnline
|
||||
case discord.DoNotDisturbStatus:
|
||||
case gateway.DoNotDisturbStatus:
|
||||
return cchat.StatusBusy
|
||||
case discord.IdleStatus:
|
||||
case gateway.IdleStatus:
|
||||
return cchat.StatusAway
|
||||
case discord.OfflineStatus, discord.InvisibleStatus:
|
||||
case gateway.OfflineStatus, gateway.InvisibleStatus:
|
||||
return cchat.StatusOffline
|
||||
default:
|
||||
return cchat.StatusUnknown
|
||||
|
@ -100,15 +100,11 @@ func (l *Member) Status() cchat.Status {
|
|||
}
|
||||
|
||||
func (l *Member) Secondary() text.Rich {
|
||||
p, err := l.channel.State.Store.Presence(l.channel.GuildID, l.userID)
|
||||
p, err := l.channel.State.Cabinet.Presence(l.channel.GuildID, l.userID)
|
||||
if err != nil {
|
||||
return text.Plain("")
|
||||
}
|
||||
|
||||
if p.Game != nil {
|
||||
return formatSmallActivity(*p.Game)
|
||||
}
|
||||
|
||||
if len(p.Activities) > 0 {
|
||||
return formatSmallActivity(p.Activities[0])
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ package memberlist
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/ningen/states/member"
|
||||
"github.com/diamondburned/ningen/v2/states/member"
|
||||
)
|
||||
|
||||
func seekPrevGroup(l *member.List, ix int) (item, group gateway.GuildMemberListOpItem) {
|
||||
|
|
|
@ -3,8 +3,8 @@ package memberlist
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message/action"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message/backlog"
|
||||
|
|
|
@ -2,74 +2,91 @@ package nickname
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/funcutil"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Nicknamer struct {
|
||||
userID discord.UserID
|
||||
shared.Channel
|
||||
}
|
||||
|
||||
func New(ch shared.Channel) cchat.Nicknamer {
|
||||
return Nicknamer{ch}
|
||||
return NewMember(ch.State.UserID, ch)
|
||||
}
|
||||
|
||||
func NewMember(userID discord.UserID, ch shared.Channel) cchat.Nicknamer {
|
||||
return Nicknamer{userID, ch}
|
||||
}
|
||||
|
||||
func (nn Nicknamer) Nickname(ctx context.Context, labeler cchat.LabelContainer) (func(), error) {
|
||||
// We don't have a nickname if we're not in a guild.
|
||||
if !nn.GuildID.IsValid() {
|
||||
// Use the current user.
|
||||
u, err := nn.State.Cabinet.Me()
|
||||
if err == nil {
|
||||
labeler.SetLabel(text.Plain(fmt.Sprintf("%s#%s", u.Username, u.Discriminator)))
|
||||
}
|
||||
|
||||
return func() {}, nil
|
||||
}
|
||||
|
||||
return funcutil.JoinCancels(
|
||||
nn.State.AddHandler(func(chunks *gateway.GuildMembersChunkEvent) {
|
||||
if chunks.GuildID != nn.GuildID {
|
||||
return
|
||||
}
|
||||
for _, member := range chunks.Members {
|
||||
if member.User.ID == nn.userID {
|
||||
nn.setMember(labeler, member)
|
||||
break
|
||||
}
|
||||
}
|
||||
}),
|
||||
nn.State.AddHandler(func(g *gateway.GuildMemberUpdateEvent) {
|
||||
if g.GuildID == nn.GuildID && g.User.ID == nn.userID {
|
||||
nn.setMember(labeler, discord.Member{
|
||||
User: g.User,
|
||||
Nick: g.Nick,
|
||||
RoleIDs: g.RoleIDs,
|
||||
})
|
||||
}
|
||||
}),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (nn Nicknamer) tryNicknameLabel(ctx context.Context, labeler cchat.LabelContainer) {
|
||||
state := nn.State.WithContext(ctx)
|
||||
|
||||
// MemberColor should fill up the state cache.
|
||||
c, err := state.MemberColor(nn.GuildID, nn.State.UserID)
|
||||
m, err := state.Cabinet.Member(nn.GuildID, nn.userID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to get self member color")
|
||||
return
|
||||
}
|
||||
|
||||
m, err := state.Member(nn.GuildID, nn.State.UserID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to get self member")
|
||||
}
|
||||
nn.setMember(labeler, *m)
|
||||
}
|
||||
|
||||
func (nn Nicknamer) setMember(labeler cchat.LabelContainer, m discord.Member) {
|
||||
var rich = text.Rich{Content: m.User.Username}
|
||||
if m.Nick != "" {
|
||||
rich.Content = m.Nick
|
||||
}
|
||||
if c > 0 {
|
||||
rich.Segments = []text.Segment{
|
||||
colored.New(len(rich.Content), c.Uint32()),
|
||||
|
||||
guild, err := nn.State.Cabinet.Guild(nn.GuildID)
|
||||
if err == nil {
|
||||
if color := discord.MemberColor(*guild, m); color > 0 {
|
||||
rich.Segments = []text.Segment{
|
||||
colored.New(len(rich.Content), color.Uint32()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
labeler.SetLabel(rich)
|
||||
|
||||
// Copy the user ID to use.
|
||||
var selfID = m.User.ID
|
||||
|
||||
return nn.State.AddHandler(func(g *gateway.GuildMemberUpdateEvent) {
|
||||
if g.GuildID != nn.GuildID || g.User.ID != selfID {
|
||||
return
|
||||
}
|
||||
|
||||
var rich = text.Rich{Content: m.User.Username}
|
||||
if m.Nick != "" {
|
||||
rich.Content = m.Nick
|
||||
}
|
||||
|
||||
c, err := nn.State.MemberColor(g.GuildID, selfID)
|
||||
if err == nil {
|
||||
rich.Segments = []text.Segment{
|
||||
colored.New(len(rich.Content), c.Uint32()),
|
||||
}
|
||||
}
|
||||
|
||||
labeler.SetLabel(rich)
|
||||
}), nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package complete
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
@ -19,7 +19,7 @@ func (ch ChannelCompleter) CompleteChannels(word string) []cchat.CompletionEntry
|
|||
return nil
|
||||
}
|
||||
|
||||
c, err := ch.State.Store.Channels(ch.GuildID)
|
||||
c, err := ch.State.Cabinet.Channels(ch.GuildID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ func (ch ChannelCompleter) CompleteChannels(word string) []cchat.CompletionEntry
|
|||
}
|
||||
|
||||
func DMChannels(s *state.Instance, word string) []cchat.CompletionEntry {
|
||||
channels, err := s.Store.PrivateChannels()
|
||||
channels, err := s.Cabinet.PrivateChannels()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func DMChannels(s *state.Instance, word string) []cchat.CompletionEntry {
|
|||
func rankChannel(word string, ch discord.Channel) int {
|
||||
switch ch.Type {
|
||||
case discord.GroupDM, discord.DirectMessage:
|
||||
return rankFunc(word, ch.Name+" "+shared.PrivateName(ch))
|
||||
return rankFunc(word, ch.Name+" "+shared.ChannelName(ch))
|
||||
default:
|
||||
return rankFunc(word, ch.Name)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func completeChannels(
|
|||
|
||||
var category string
|
||||
if s != nil && channel.CategoryID.IsValid() {
|
||||
if cat, _ := s.Store.Channel(channel.CategoryID); cat != nil {
|
||||
if cat, _ := s.Cabinet.Channel(channel.CategoryID); cat != nil {
|
||||
category = cat.Name
|
||||
}
|
||||
}
|
||||
|
@ -86,5 +86,4 @@ func completeChannels(
|
|||
|
||||
sortDistances(entries, distances)
|
||||
return entries
|
||||
|
||||
}
|
||||
|
|
|
@ -14,16 +14,23 @@ type ChannelCompleter struct {
|
|||
shared.Channel
|
||||
}
|
||||
|
||||
type Completer map[byte]CompleterFunc
|
||||
type CompleterPrefixes map[byte]CompleterFunc
|
||||
|
||||
type Completer struct {
|
||||
Prefixes CompleterPrefixes
|
||||
SlashHandler cchat.Completer
|
||||
}
|
||||
|
||||
const MaxCompletion = 15
|
||||
|
||||
func New(ch shared.Channel) cchat.Completer {
|
||||
completer := ChannelCompleter{ch}
|
||||
return Completer{
|
||||
'@': completer.CompleteMentions,
|
||||
'#': completer.CompleteChannels,
|
||||
':': completer.CompleteEmojis,
|
||||
Prefixes: map[byte]CompleterFunc{
|
||||
'@': completer.CompleteMentions,
|
||||
'#': completer.CompleteChannels,
|
||||
':': completer.CompleteEmojis,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,20 +38,24 @@ func New(ch shared.Channel) cchat.Completer {
|
|||
// This method supports user mentions, channel mentions and emojis.
|
||||
//
|
||||
// For the individual implementations, refer to channel_completion.go.
|
||||
func (ch Completer) Complete(words []string, i int64) []cchat.CompletionEntry {
|
||||
func (cc Completer) Complete(words []string, i int64) []cchat.CompletionEntry {
|
||||
var word = words[i]
|
||||
// Word should have at least a character for the char check.
|
||||
if len(word) < 1 {
|
||||
if len(word) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
fn, ok := ch[word[0]]
|
||||
// Always check the first word for slash, not the current word.
|
||||
if cc.SlashHandler != nil && words[0][0] == '/' {
|
||||
return cc.SlashHandler.Complete(words, i)
|
||||
}
|
||||
|
||||
fn, ok := cc.Prefixes[word[0]]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
fn(word[1:])
|
||||
return nil
|
||||
return fn(word[1:])
|
||||
}
|
||||
|
||||
// rankFunc is the default rank function to use.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package complete
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
package complete
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/message"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
@ -29,8 +28,8 @@ func GuildMessageMentions(
|
|||
// Keep track of the number of authors.
|
||||
// TODO: fix excess allocations
|
||||
|
||||
var entries []cchat.CompletionEntry
|
||||
var authors map[discord.UserID]struct{}
|
||||
var entries = make([]cchat.CompletionEntry, 0, MaxCompletion)
|
||||
var authors = make(map[discord.UserID]struct{}, MaxCompletion)
|
||||
|
||||
for _, msg := range msgs {
|
||||
// If we've already added the author into the list, then skip.
|
||||
|
@ -38,13 +37,12 @@ func GuildMessageMentions(
|
|||
continue
|
||||
}
|
||||
|
||||
ensureAuthorMapMade(&authors)
|
||||
authors[msg.Author.ID] = struct{}{}
|
||||
|
||||
var rich text.Rich
|
||||
|
||||
if guild != nil && state != nil {
|
||||
m, err := state.Store.Member(guild.ID, msg.Author.ID)
|
||||
m, err := state.Cabinet.Member(guild.ID, msg.Author.ID)
|
||||
if err == nil {
|
||||
rich = message.RenderMemberName(*m, *guild, state)
|
||||
}
|
||||
|
@ -55,8 +53,6 @@ func GuildMessageMentions(
|
|||
rich = text.Plain(msg.Author.Username)
|
||||
}
|
||||
|
||||
ensureEntriesMade(&entries)
|
||||
|
||||
entries = append(entries, cchat.CompletionEntry{
|
||||
Raw: msg.Author.Mention(),
|
||||
Text: rich,
|
||||
|
@ -72,72 +68,131 @@ func GuildMessageMentions(
|
|||
return entries
|
||||
}
|
||||
|
||||
func ensureAuthorMapMade(authors *map[discord.UserID]struct{}) {
|
||||
if *authors == nil {
|
||||
*authors = make(map[discord.UserID]struct{}, MaxCompletion)
|
||||
}
|
||||
}
|
||||
|
||||
func Presences(s *state.Instance, word string) []cchat.CompletionEntry {
|
||||
presences, err := s.Presences(0)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
// AllUsers checks for friends and presences.
|
||||
func AllUsers(s *state.Instance, word string) []cchat.CompletionEntry {
|
||||
var full bool
|
||||
|
||||
var friends map[discord.UserID]struct{}
|
||||
var entries []cchat.CompletionEntry
|
||||
var distances map[string]int
|
||||
|
||||
for _, presence := range presences {
|
||||
rank := rankFunc(word, presence.User.Username)
|
||||
// Search for friends first.
|
||||
s.RelationshipState.Each(func(r *discord.Relationship) bool {
|
||||
// Skip blocked users or strangers.
|
||||
if r.Type == 0 || r.Type == discord.BlockedRelationship {
|
||||
return false
|
||||
}
|
||||
|
||||
rank := rankFunc(word, r.User.Username)
|
||||
if rank == -1 {
|
||||
continue
|
||||
return false
|
||||
}
|
||||
|
||||
if friends == nil {
|
||||
friends = map[discord.UserID]struct{}{}
|
||||
}
|
||||
|
||||
friends[r.UserID] = struct{}{}
|
||||
|
||||
ensureEntriesMade(&entries)
|
||||
ensureDistancesMade(&distances)
|
||||
|
||||
raw := r.User.Mention()
|
||||
|
||||
var status = gateway.UnknownStatus
|
||||
if p, _ := s.PresenceState.Presence(0, r.UserID); p != nil {
|
||||
status = p.Status
|
||||
}
|
||||
|
||||
entries = append(entries, cchat.CompletionEntry{
|
||||
Raw: raw,
|
||||
Text: text.Plain(r.User.Username + "#" + r.User.Discriminator),
|
||||
Secondary: text.Plain(FormatStatus(status) + " - " + FormatRelationshipType(r.Type)),
|
||||
IconURL: r.User.AvatarURL(),
|
||||
})
|
||||
|
||||
distances[raw] = rank
|
||||
|
||||
full = len(entries) >= MaxCompletion
|
||||
return full
|
||||
})
|
||||
|
||||
if full {
|
||||
goto Full
|
||||
}
|
||||
|
||||
// Search for presences.
|
||||
s.PresenceState.Each(0, func(p *gateway.Presence) bool {
|
||||
// Avoid duplicates.
|
||||
if _, ok := friends[p.User.ID]; ok {
|
||||
return false
|
||||
}
|
||||
|
||||
rank := rankFunc(word, p.User.Username)
|
||||
if rank == -1 {
|
||||
return false
|
||||
}
|
||||
|
||||
ensureEntriesMade(&entries)
|
||||
ensureDistancesMade(&distances)
|
||||
|
||||
raw := presence.User.Mention()
|
||||
raw := p.User.Mention()
|
||||
|
||||
entries = append(entries, cchat.CompletionEntry{
|
||||
Raw: raw,
|
||||
Text: text.Plain(presence.User.Username + "#" + presence.User.Discriminator),
|
||||
Secondary: text.Plain(FormatStatus(presence.Status)),
|
||||
IconURL: presence.User.AvatarURL(),
|
||||
Text: text.Plain(p.User.Username + "#" + p.User.Discriminator),
|
||||
Secondary: text.Plain(FormatStatus(p.Status)),
|
||||
IconURL: p.User.AvatarURL(),
|
||||
})
|
||||
|
||||
distances[raw] = rank
|
||||
|
||||
if len(entries) >= MaxCompletion {
|
||||
break
|
||||
}
|
||||
}
|
||||
full = len(entries) >= MaxCompletion
|
||||
return full
|
||||
})
|
||||
|
||||
Full:
|
||||
sortDistances(entries, distances)
|
||||
return entries
|
||||
}
|
||||
|
||||
func FormatStatus(status discord.Status) string {
|
||||
func FormatStatus(status gateway.Status) string {
|
||||
switch status {
|
||||
case discord.OnlineStatus:
|
||||
case gateway.OnlineStatus:
|
||||
return "Online"
|
||||
case discord.DoNotDisturbStatus:
|
||||
case gateway.DoNotDisturbStatus:
|
||||
return "Busy"
|
||||
case discord.IdleStatus:
|
||||
case gateway.IdleStatus:
|
||||
return "Idle"
|
||||
case discord.InvisibleStatus:
|
||||
case gateway.InvisibleStatus:
|
||||
return "Invisible"
|
||||
case discord.OfflineStatus:
|
||||
return "Offline"
|
||||
case gateway.OfflineStatus:
|
||||
fallthrough
|
||||
default:
|
||||
return strings.Title(string(status))
|
||||
return "Offline"
|
||||
}
|
||||
}
|
||||
|
||||
func FormatRelationshipType(relaType discord.RelationshipType) string {
|
||||
switch relaType {
|
||||
case discord.BlockedRelationship:
|
||||
return "Blocked"
|
||||
case discord.FriendRelationship:
|
||||
return "Friend"
|
||||
case discord.IncomingFriendRequest:
|
||||
return "Incoming friend request"
|
||||
case discord.SentFriendRequest:
|
||||
return "Friend request sent"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func (ch ChannelCompleter) CompleteMentions(word string) []cchat.CompletionEntry {
|
||||
// If there is no input, then we should grab the latest messages.
|
||||
if word == "" {
|
||||
msgs, _ := ch.State.Store.Messages(ch.ID)
|
||||
g, _ := ch.State.Store.Guild(ch.GuildID) // nil is fine
|
||||
msgs, _ := ch.State.Cabinet.Messages(ch.ID)
|
||||
g, _ := ch.State.Cabinet.Guild(ch.GuildID) // nil is fine
|
||||
|
||||
return GuildMessageMentions(msgs, ch.State, g)
|
||||
}
|
||||
|
@ -147,7 +202,7 @@ func (ch ChannelCompleter) CompleteMentions(word string) []cchat.CompletionEntry
|
|||
|
||||
// If we're not in a guild, then we can check the list of recipients.
|
||||
if !ch.GuildID.IsValid() {
|
||||
c, err := ch.State.Store.Channel(ch.ID)
|
||||
c, err := ch.State.Cabinet.Channel(ch.ID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -182,8 +237,8 @@ func (ch ChannelCompleter) CompleteMentions(word string) []cchat.CompletionEntry
|
|||
}
|
||||
|
||||
// If we're in a guild, then we should search for (all) members.
|
||||
m, merr := ch.State.Store.Members(ch.GuildID)
|
||||
g, gerr := ch.State.Store.Guild(ch.GuildID)
|
||||
m, merr := ch.State.Cabinet.Members(ch.GuildID)
|
||||
g, gerr := ch.State.Cabinet.Guild(ch.GuildID)
|
||||
|
||||
if merr != nil || gerr != nil {
|
||||
return nil
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package send
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/api"
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/api"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/utils/sendpart"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message/send/complete"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
|
@ -50,10 +51,10 @@ func (s Sender) AsCompleter() cchat.Completer {
|
|||
return complete.New(s.Channel)
|
||||
}
|
||||
|
||||
func addAttachments(atts []cchat.MessageAttachment) []api.SendMessageFile {
|
||||
var files = make([]api.SendMessageFile, len(atts))
|
||||
func addAttachments(atts []cchat.MessageAttachment) []sendpart.File {
|
||||
var files = make([]sendpart.File, len(atts))
|
||||
for i, a := range atts {
|
||||
files[i] = api.SendMessageFile{
|
||||
files[i] = sendpart.File{
|
||||
Name: a.Name,
|
||||
Reader: a,
|
||||
}
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
package channel
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Private struct {
|
||||
Channel
|
||||
}
|
||||
|
||||
var _ cchat.Server = (*Private)(nil)
|
||||
|
||||
func NewPrivate(s *state.Instance, ch discord.Channel) (cchat.Server, error) {
|
||||
if ch.GuildID.IsValid() {
|
||||
return nil, errors.New("channel has valid guild ID: not a DM")
|
||||
}
|
||||
|
||||
channel, err := NewChannel(s, ch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return Private{Channel: channel}, nil
|
||||
}
|
||||
|
||||
func (priv Private) Name() text.Rich {
|
||||
c, err := priv.Self()
|
||||
if err != nil {
|
||||
return text.Rich{Content: priv.ID()}
|
||||
}
|
||||
|
||||
return text.Plain(shared.PrivateName(*c))
|
||||
}
|
||||
|
||||
func (priv Private) AsIconer() cchat.Iconer {
|
||||
return NewAvatarIcon(priv.State)
|
||||
}
|
||||
|
||||
type AvatarIcon struct {
|
||||
State *state.Instance
|
||||
}
|
||||
|
||||
func NewAvatarIcon(state *state.Instance) cchat.Iconer {
|
||||
return AvatarIcon{state}
|
||||
}
|
||||
|
||||
func (avy AvatarIcon) Icon(ctx context.Context, iconer cchat.IconContainer) (func(), error) {
|
||||
u, err := avy.State.WithContext(ctx).Me()
|
||||
if err != nil {
|
||||
// This shouldn't happen.
|
||||
return nil, errors.Wrap(err, "Failed to get guild")
|
||||
}
|
||||
|
||||
// Used for comparison.
|
||||
if u.Avatar != "" {
|
||||
iconer.SetIcon(urlutils.AvatarURL(u.AvatarURL()))
|
||||
}
|
||||
|
||||
selfID := u.ID
|
||||
|
||||
return avy.State.AddHandler(func(update *gateway.UserUpdateEvent) {
|
||||
if selfID == update.ID {
|
||||
iconer.SetIcon(urlutils.AvatarURL(update.AvatarURL()))
|
||||
}
|
||||
}), nil
|
||||
}
|
|
@ -5,18 +5,32 @@ import (
|
|||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
)
|
||||
|
||||
// PrivateName returns the channel name if any, otherwise it formats its own
|
||||
// ChannelName returns the channel name if any, otherwise it formats its own
|
||||
// name into a list of recipients.
|
||||
func PrivateName(privCh discord.Channel) string {
|
||||
if privCh.Name != "" {
|
||||
return privCh.Name
|
||||
func ChannelName(ch discord.Channel) string {
|
||||
switch ch.Type {
|
||||
case discord.DirectMessage, discord.GroupDM:
|
||||
if len(ch.DMRecipients) > 0 {
|
||||
return FormatRecipients(ch.DMRecipients)
|
||||
}
|
||||
|
||||
default:
|
||||
if ch.Name == "" {
|
||||
break
|
||||
}
|
||||
|
||||
if ch.NSFW {
|
||||
return "#" + ch.Name + " (nsfw)"
|
||||
} else {
|
||||
return "#" + ch.Name
|
||||
}
|
||||
}
|
||||
|
||||
return FormatRecipients(privCh.DMRecipients)
|
||||
return ch.ID.String()
|
||||
}
|
||||
|
||||
// FormatRecipients joins the given list of users into a string listing all
|
||||
|
@ -24,14 +38,14 @@ func PrivateName(privCh discord.Channel) string {
|
|||
func FormatRecipients(users []discord.User) string {
|
||||
switch len(users) {
|
||||
case 0:
|
||||
return "<Nobody>"
|
||||
return ""
|
||||
case 1:
|
||||
return users[0].Username
|
||||
case 2:
|
||||
return users[0].Username + " and " + users[1].Username
|
||||
}
|
||||
|
||||
var usernames = make([]string, len(users))
|
||||
var usernames = make([]string, len(users)-1)
|
||||
for i, user := range users[:len(users)-1] {
|
||||
usernames[i] = user.Username
|
||||
}
|
||||
|
@ -48,6 +62,11 @@ type Channel struct {
|
|||
// HasPermission returns true if the current user has the given permissions in
|
||||
// the channel.
|
||||
func (ch Channel) HasPermission(perms ...discord.Permissions) bool {
|
||||
// Assume we have permissions in a direct message channel.
|
||||
if !ch.GuildID.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
p, err := ch.State.StateOnly().Permissions(ch.ID, ch.State.UserID)
|
||||
if err != nil {
|
||||
return false
|
||||
|
@ -63,16 +82,16 @@ func (ch Channel) HasPermission(perms ...discord.Permissions) bool {
|
|||
}
|
||||
|
||||
func (ch Channel) Messages() ([]discord.Message, error) {
|
||||
return ch.State.Store.Messages(ch.ID)
|
||||
return ch.State.Cabinet.Messages(ch.ID)
|
||||
}
|
||||
|
||||
func (ch Channel) Guild() (*discord.Guild, error) {
|
||||
if !ch.GuildID.IsValid() {
|
||||
return nil, errors.New("channel not in guild")
|
||||
}
|
||||
return ch.State.Store.Guild(ch.GuildID)
|
||||
return ch.State.Cabinet.Guild(ch.GuildID)
|
||||
}
|
||||
|
||||
func (ch Channel) Self() (*discord.Channel, error) {
|
||||
return ch.State.Store.Channel(ch.ID)
|
||||
return ch.State.Cabinet.Channel(ch.ID)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/message"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
@ -27,13 +27,13 @@ func NewFromAuthor(author message.Author, ev *gateway.TypingStartEvent) Typer {
|
|||
|
||||
func New(s *state.Instance, ev *gateway.TypingStartEvent) (*Typer, error) {
|
||||
if ev.GuildID.IsValid() {
|
||||
g, err := s.Store.Guild(ev.GuildID)
|
||||
g, err := s.Cabinet.Guild(ev.GuildID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ev.Member == nil {
|
||||
ev.Member, err = s.Store.Member(ev.GuildID, ev.UserID)
|
||||
ev.Member, err = s.Cabinet.Member(ev.GuildID, ev.UserID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ func New(s *state.Instance, ev *gateway.TypingStartEvent) (*Typer, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
c, err := s.Store.Channel(ev.ChannelID)
|
||||
c, err := s.Cabinet.Channel(ev.ChannelID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/guild"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
|
@ -25,7 +25,7 @@ func New(s *state.Instance, gf gateway.GuildFolder) cchat.Server {
|
|||
var names = make([]string, 0, len(gf.GuildIDs))
|
||||
|
||||
for _, id := range gf.GuildIDs {
|
||||
g, err := s.Store.Guild(id)
|
||||
g, err := s.Cabinet.Guild(id)
|
||||
if err == nil {
|
||||
names = append(names, g.Name)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"context"
|
||||
"sort"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/category"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel"
|
||||
|
@ -43,7 +43,7 @@ func (g *Guild) self(ctx context.Context) (*discord.Guild, error) {
|
|||
}
|
||||
|
||||
func (g *Guild) selfState() (*discord.Guild, error) {
|
||||
return g.state.Store.Guild(g.id)
|
||||
return g.state.Cabinet.Guild(g.id)
|
||||
}
|
||||
|
||||
func (g *Guild) ID() cchat.ID {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package message
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
||||
|
@ -132,25 +132,31 @@ func (a *Author) AddReply(name string) {
|
|||
// richMember(&a.name, m, g, s)
|
||||
// }
|
||||
|
||||
func (a *Author) addAuthorReference(msgref discord.Message, s *state.Instance) {
|
||||
a.name.Content += authorReplyingTo
|
||||
start, end := richUser(&a.name, msgref.Author, s)
|
||||
|
||||
a.name.Segments = append(a.name.Segments,
|
||||
reference.NewMessageSegment(start, end, msgref.ID),
|
||||
)
|
||||
}
|
||||
|
||||
// AddMessageReference adds a message reference to the author.
|
||||
func (a *Author) AddMessageReference(msgref discord.Message, s *state.Instance) {
|
||||
if !msgref.GuildID.IsValid() {
|
||||
a.name.Content += authorReplyingTo
|
||||
start, end := richUser(&a.name, msgref.Author, s)
|
||||
|
||||
a.name.Segments = append(a.name.Segments,
|
||||
reference.NewMessageSegment(start, end, msgref.ID),
|
||||
)
|
||||
a.addAuthorReference(msgref, s)
|
||||
return
|
||||
}
|
||||
|
||||
g, err := s.Guild(msgref.GuildID)
|
||||
g, err := s.Cabinet.Guild(msgref.GuildID)
|
||||
if err != nil {
|
||||
a.addAuthorReference(msgref, s)
|
||||
return
|
||||
}
|
||||
|
||||
m, err := s.Member(g.ID, msgref.Author.ID)
|
||||
m, err := s.Cabinet.Member(g.ID, msgref.Author.ID)
|
||||
if err != nil {
|
||||
a.addAuthorReference(msgref, s)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ package message
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments"
|
||||
|
@ -85,13 +85,13 @@ func NewMessageUpdateContent(msg discord.Message, s *state.Instance) Message {
|
|||
// Check if content is empty.
|
||||
if msg.Content == "" {
|
||||
// Then grab the content from the state.
|
||||
m, err := s.Store.Message(msg.ChannelID, msg.ID)
|
||||
m, err := s.Cabinet.Message(msg.ChannelID, msg.ID)
|
||||
if err == nil {
|
||||
msg.Content = m.Content
|
||||
}
|
||||
}
|
||||
|
||||
var content = segments.ParseMessage(&msg, s.Store)
|
||||
var content = segments.ParseMessage(&msg, s.Cabinet)
|
||||
return Message{
|
||||
messageHeader: newHeader(msg),
|
||||
content: content,
|
||||
|
@ -116,13 +116,13 @@ func NewGuildMessageCreate(c *gateway.MessageCreateEvent, s *state.Instance) Mes
|
|||
message.Nonce = s.Nonces.Load(c.Nonce)
|
||||
|
||||
// This should not error.
|
||||
g, err := s.Store.Guild(c.GuildID)
|
||||
g, err := s.Cabinet.Guild(c.GuildID)
|
||||
if err != nil {
|
||||
return NewMessage(message, s, NewUser(c.Author, s))
|
||||
}
|
||||
|
||||
if c.Member == nil {
|
||||
c.Member, _ = s.Store.Member(c.GuildID, c.Author.ID)
|
||||
c.Member, _ = s.Cabinet.Member(c.GuildID, c.Author.ID)
|
||||
}
|
||||
if c.Member == nil {
|
||||
s.MemberState.RequestMember(c.GuildID, c.Author.ID)
|
||||
|
@ -142,7 +142,7 @@ func NewBacklogMessage(m discord.Message, s *state.Instance, g discord.Guild) Me
|
|||
return NewMessage(m, s, NewUser(m.Author, s))
|
||||
}
|
||||
|
||||
mem, err := s.Store.Member(m.GuildID, m.Author.ID)
|
||||
mem, err := s.Cabinet.Member(m.GuildID, m.Author.ID)
|
||||
if err != nil {
|
||||
s.MemberState.RequestMember(m.GuildID, m.Author.ID)
|
||||
return NewMessage(m, s, NewUser(m.Author, s))
|
||||
|
@ -157,7 +157,7 @@ func NewDirectMessage(m discord.Message, s *state.Instance) Message {
|
|||
|
||||
func NewMessage(m discord.Message, s *state.Instance, author Author) Message {
|
||||
// Render the message content.
|
||||
var content = segments.ParseMessage(&m, s.Store)
|
||||
var content = segments.ParseMessage(&m, s.Cabinet)
|
||||
|
||||
// Request members in mentions if we're in a guild.
|
||||
if m.GuildID.IsValid() {
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message/send/complete"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/shared"
|
||||
|
@ -83,13 +83,13 @@ func NewMessages(s *state.Instance, acList *activeList, adder ChannelAdder) *Mes
|
|||
messages: make(messageList, 0, 100),
|
||||
}
|
||||
|
||||
hubServer.sender.completers = complete.Completer{
|
||||
hubServer.sender.completers.Prefixes = complete.CompleterPrefixes{
|
||||
':': func(word string) []cchat.CompletionEntry {
|
||||
return complete.Emojis(s, 0, word)
|
||||
},
|
||||
'@': func(word string) []cchat.CompletionEntry {
|
||||
if word != "" {
|
||||
return complete.Presences(s, word)
|
||||
return complete.AllUsers(s, word)
|
||||
}
|
||||
|
||||
hubServer.msgMutex.Lock()
|
||||
|
@ -175,7 +175,7 @@ func (msgs *Messages) JoinServer(ctx context.Context, ct cchat.MessagesContainer
|
|||
case discord.DirectMessage:
|
||||
author.AddUserReply(c.DMRecipients[0], msgs.state)
|
||||
case discord.GroupDM:
|
||||
author.AddReply(shared.PrivateName(*c))
|
||||
author.AddReply(shared.ChannelName(*c))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message/send"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel/message/send/complete"
|
||||
|
@ -61,8 +61,6 @@ func (s *Sender) Send(sendable cchat.SendableMessage) error {
|
|||
return errors.New("message must start with a user or channel mention")
|
||||
}
|
||||
|
||||
// TODO: account for channel names
|
||||
|
||||
targetID, err := discord.ParseSnowflake(matches[2])
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to parse recipient ID")
|
||||
|
@ -79,8 +77,17 @@ func (s *Sender) Send(sendable cchat.SendableMessage) error {
|
|||
return errors.New("unknown channel")
|
||||
}
|
||||
|
||||
s.adder.AddChannel(s.state, channel)
|
||||
s.acList.add(channel.ID)
|
||||
switch channel.Type {
|
||||
case discord.DirectMessage, discord.GroupDM:
|
||||
// valid
|
||||
default:
|
||||
return errors.New("not a [group] direct message channel")
|
||||
}
|
||||
|
||||
// We should only add the channel if it's not already in the active list.
|
||||
if s.acList.add(channel.ID) {
|
||||
s.adder.AddChannel(s.state, channel)
|
||||
}
|
||||
|
||||
sendData := send.WrapMessage(s.state, sendable)
|
||||
sendData.Content = strings.TrimPrefix(content, matches[0])
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
|
@ -12,8 +12,8 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// automatically add all channels with active messages within the past 48 hours.
|
||||
const autoAddActive = 24 * time.Hour
|
||||
// automatically add all channels with active messages within the past 5 days.
|
||||
const autoAddActive = 5 * 24 * time.Hour
|
||||
|
||||
// activeList contains a list of channel IDs that should be put into its own
|
||||
// channels.
|
||||
|
@ -32,7 +32,14 @@ func makeActiveList(s *state.Instance) (*activeList, error) {
|
|||
now := time.Now()
|
||||
|
||||
for _, channel := range channels {
|
||||
if channel.LastMessageID.Time().Add(autoAddActive).After(now) {
|
||||
switch channel.Type {
|
||||
case discord.DirectMessage, discord.GroupDM:
|
||||
// valid
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
if channelIsActive(s, channel, now) {
|
||||
ids[channel.ID] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +47,42 @@ func makeActiveList(s *state.Instance) (*activeList, error) {
|
|||
return &activeList{active: ids}, nil
|
||||
}
|
||||
|
||||
func channelIsActive(s *state.Instance, ch discord.Channel, now time.Time) bool {
|
||||
// Never show a muted channel, unless requested.
|
||||
muted := s.MutedState.Channel(ch.ID)
|
||||
if muted {
|
||||
return false
|
||||
}
|
||||
|
||||
read := s.ReadState.FindLast(ch.ID)
|
||||
|
||||
// recently created channel
|
||||
if ch.ID.Time().Add(autoAddActive).After(now) {
|
||||
return true
|
||||
}
|
||||
|
||||
var lastMsg discord.MessageID
|
||||
if read != nil && read.LastMessageID.IsValid() {
|
||||
lastMsg = read.LastMessageID
|
||||
}
|
||||
if ch.LastMessageID > lastMsg {
|
||||
// We have a valid message ID in the read state and it is smaller than
|
||||
// the last message in the channel, so this channel is not read.
|
||||
if lastMsg.IsValid() {
|
||||
return true
|
||||
}
|
||||
|
||||
lastMsg = ch.LastMessageID
|
||||
}
|
||||
|
||||
// last message is recent
|
||||
if lastMsg.IsValid() && lastMsg.Time().Add(autoAddActive).After(now) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (acList *activeList) list() []discord.ChannelID {
|
||||
acList.mut.Lock()
|
||||
defer acList.mut.Unlock()
|
||||
|
|
|
@ -4,7 +4,8 @@ import (
|
|||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/channel"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/private/hub"
|
||||
|
@ -37,8 +38,13 @@ func (cset *containerSet) Register(container cchat.ServersContainer) {
|
|||
// top of the servers container.
|
||||
type prependServer struct{ cchat.Server }
|
||||
|
||||
var _ cchat.ServerUpdate = (*prependServer)(nil)
|
||||
|
||||
// PreviousID returns the appropriate parameters to prepend this server.
|
||||
func (ps prependServer) PreviousID() (cchat.ID, bool) { return "", false }
|
||||
func (ps prependServer) PreviousID() (cchat.ID, bool) {
|
||||
// Return the private container's ID so this server goes right after it.
|
||||
return "!!!private-container!!!", false
|
||||
}
|
||||
|
||||
func (cset *containerSet) AddChannel(s *state.Instance, ch *discord.Channel) {
|
||||
c, err := channel.New(s, *ch)
|
||||
|
@ -90,9 +96,29 @@ func (priv Private) Name() text.Rich {
|
|||
|
||||
func (priv Private) AsLister() cchat.Lister { return priv }
|
||||
|
||||
type activeChannel struct {
|
||||
*discord.Channel
|
||||
*gateway.ReadState // used for sorting
|
||||
}
|
||||
|
||||
func (active activeChannel) LastMessageID() discord.MessageID {
|
||||
if active.ReadState == nil {
|
||||
return active.Channel.LastMessageID
|
||||
}
|
||||
if active.ReadState.LastMessageID > active.Channel.LastMessageID {
|
||||
return active.ReadState.LastMessageID
|
||||
}
|
||||
if active.Channel.LastMessageID.IsValid() {
|
||||
return active.Channel.LastMessageID
|
||||
}
|
||||
// Whatever.
|
||||
return discord.MessageID(active.Channel.ID)
|
||||
}
|
||||
|
||||
func (priv Private) Servers(container cchat.ServersContainer) error {
|
||||
activeIDs := priv.hub.ActiveChannelIDs()
|
||||
channels := make([]*discord.Channel, 0, len(activeIDs))
|
||||
|
||||
channels := make([]activeChannel, 0, len(activeIDs))
|
||||
|
||||
for _, id := range activeIDs {
|
||||
c, err := priv.state.Channel(id)
|
||||
|
@ -100,25 +126,28 @@ func (priv Private) Servers(container cchat.ServersContainer) error {
|
|||
return errors.Wrap(err, "failed to get private channel")
|
||||
}
|
||||
|
||||
channels = append(channels, c)
|
||||
channels = append(channels, activeChannel{
|
||||
Channel: c,
|
||||
ReadState: priv.state.ReadState.FindLast(id),
|
||||
})
|
||||
}
|
||||
|
||||
// Sort so that channels with the largest last message ID (and therefore the
|
||||
// latest message) will be on top.
|
||||
sort.Slice(channels, func(i, j int) bool {
|
||||
return channels[i].LastMessageID > channels[j].LastMessageID
|
||||
return channels[i].LastMessageID() > channels[j].LastMessageID()
|
||||
})
|
||||
|
||||
servers := make([]cchat.Server, len(channels)+1)
|
||||
servers[0] = priv.hub
|
||||
|
||||
for i, ch := range channels {
|
||||
c, err := channel.New(priv.state, *ch)
|
||||
c, err := channel.New(priv.state, *ch.Channel)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create server for private channel")
|
||||
}
|
||||
|
||||
servers[i] = c
|
||||
servers[i+1] = c
|
||||
}
|
||||
|
||||
container.SetServers(servers)
|
||||
|
|
|
@ -3,8 +3,8 @@ package session
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/diamondburned/arikawa/gateway"
|
||||
"github.com/diamondburned/arikawa/session"
|
||||
"github.com/diamondburned/arikawa/v2/gateway"
|
||||
"github.com/diamondburned/arikawa/v2/session"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/folder"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/guild"
|
||||
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/diamondburned/ningen"
|
||||
"github.com/diamondburned/ningen/v2"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -42,7 +42,7 @@ func (s *Session) ID() cchat.ID {
|
|||
}
|
||||
|
||||
func (s *Session) Name() text.Rich {
|
||||
u, err := s.state.Store.Me()
|
||||
u, err := s.state.Cabinet.Me()
|
||||
if err != nil {
|
||||
// This shouldn't happen, ever.
|
||||
return text.Rich{Content: "<@" + s.state.UserID.String() + ">"}
|
||||
|
@ -64,7 +64,7 @@ func (s *Session) Icon(ctx context.Context, iconer cchat.IconContainer) (func(),
|
|||
|
||||
return s.state.AddHandler(func(*gateway.UserUpdateEvent) {
|
||||
// Bypass the event and use the state cache.
|
||||
if u, err := s.state.Store.Me(); err == nil {
|
||||
if u, err := s.state.Cabinet.Me(); err == nil {
|
||||
iconer.SetIcon(urlutils.AvatarURL(u.AvatarURL()))
|
||||
}
|
||||
}), nil
|
||||
|
@ -91,17 +91,16 @@ func (s *Session) Servers(container cchat.ServersContainer) error {
|
|||
}
|
||||
|
||||
func (s *Session) servers(container cchat.ServersContainer) error {
|
||||
// TODO: remove this once v2 is used, so we could swap it with a getter.
|
||||
ready := s.state.Ready
|
||||
ready := s.state.Ready()
|
||||
|
||||
switch {
|
||||
// If the user has guild folders:
|
||||
case len(ready.Settings.GuildFolders) > 0:
|
||||
case len(ready.UserSettings.GuildFolders) > 0:
|
||||
// TODO: account for missing guilds.
|
||||
toplevels := make([]cchat.Server, 1, len(ready.Settings.GuildFolders)+1)
|
||||
toplevels := make([]cchat.Server, 1, len(ready.UserSettings.GuildFolders)+1)
|
||||
toplevels[0] = s.private
|
||||
|
||||
for _, guildFolder := range ready.Settings.GuildFolders {
|
||||
for _, guildFolder := range ready.UserSettings.GuildFolders {
|
||||
// TODO: correct.
|
||||
switch {
|
||||
case guildFolder.ID != 0:
|
||||
|
@ -122,11 +121,11 @@ func (s *Session) servers(container cchat.ServersContainer) error {
|
|||
|
||||
// If the user doesn't have guild folders but has sorted their guilds
|
||||
// before:
|
||||
case len(ready.Settings.GuildPositions) > 0:
|
||||
guilds := make([]cchat.Server, 1, len(ready.Settings.GuildPositions)+1)
|
||||
case len(ready.UserSettings.GuildPositions) > 0:
|
||||
guilds := make([]cchat.Server, 1, len(ready.UserSettings.GuildPositions)+1)
|
||||
guilds[0] = s.private
|
||||
|
||||
for _, id := range ready.Settings.GuildPositions {
|
||||
for _, id := range ready.UserSettings.GuildPositions {
|
||||
g, err := guild.NewFromID(s.state, id)
|
||||
if err != nil {
|
||||
continue
|
||||
|
|
|
@ -5,13 +5,14 @@ import (
|
|||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/session"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/arikawa/utils/httputil/httpdriver"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/session"
|
||||
"github.com/diamondburned/arikawa/v2/state"
|
||||
"github.com/diamondburned/arikawa/v2/state/store/defaultstore"
|
||||
"github.com/diamondburned/arikawa/v2/utils/httputil/httpdriver"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat-discord/internal/discord/state/nonce"
|
||||
"github.com/diamondburned/ningen"
|
||||
"github.com/diamondburned/ningen/v2"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -19,7 +20,8 @@ type Instance struct {
|
|||
*ningen.State
|
||||
Nonces *nonce.Map
|
||||
|
||||
// UserID is a constant user ID. It is guaranteed to be valid.
|
||||
// UserID is a constant user ID of the current user. It is guaranteed to be
|
||||
// valid.
|
||||
UserID discord.UserID
|
||||
}
|
||||
|
||||
|
@ -52,17 +54,13 @@ func Login(email, password, mfa string) (*Instance, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
state, _ := state.NewFromSession(session, state.NewDefaultStore(nil))
|
||||
return New(state)
|
||||
cabinet := defaultstore.New()
|
||||
cabinet.MessageStore = defaultstore.NewMessage(50)
|
||||
|
||||
return New(state.NewFromSession(session, cabinet))
|
||||
}
|
||||
|
||||
func New(s *state.State) (*Instance, error) {
|
||||
// Prefetch user.
|
||||
u, err := s.Me()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get current user")
|
||||
}
|
||||
|
||||
n, err := ningen.FromState(s)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create a state wrapper")
|
||||
|
@ -77,6 +75,12 @@ func New(s *state.State) (*Instance, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Prefetch user.
|
||||
u, err := s.Me()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get current user")
|
||||
}
|
||||
|
||||
return &Instance{
|
||||
UserID: u.ID,
|
||||
State: n,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package embed
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/emoji"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
|
|
|
@ -4,15 +4,15 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/state/store"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/inline"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/link"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
|
||||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
"github.com/dustin/go-humanize"
|
||||
)
|
||||
|
||||
|
@ -24,7 +24,7 @@ func writeEmbedSep(r *renderer.Text, embedColor discord.Color) {
|
|||
}
|
||||
}
|
||||
|
||||
func RenderEmbeds(r *renderer.Text, embeds []discord.Embed, m *discord.Message, s state.Store) {
|
||||
func RenderEmbeds(r *renderer.Text, embeds []discord.Embed, m *discord.Message, s store.Cabinet) {
|
||||
for _, embed := range embeds {
|
||||
r.StartBlock()
|
||||
writeEmbedSep(r, embed.Color)
|
||||
|
@ -38,7 +38,7 @@ func RenderEmbeds(r *renderer.Text, embeds []discord.Embed, m *discord.Message,
|
|||
}
|
||||
}
|
||||
|
||||
func RenderEmbed(r *renderer.Text, embed discord.Embed, m *discord.Message, s state.Store) {
|
||||
func RenderEmbed(r *renderer.Text, embed discord.Embed, m *discord.Message, s store.Cabinet) {
|
||||
if a := embed.Author; a != nil && a.Name != "" {
|
||||
if a.ProxyIcon != "" {
|
||||
r.Append(Author(r.Buffer.Len(), *a))
|
||||
|
|
|
@ -3,7 +3,7 @@ package embed
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
|
|
|
@ -3,11 +3,11 @@ package emoji
|
|||
import (
|
||||
"net/url"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
)
|
||||
|
||||
|
@ -48,6 +48,20 @@ func (attr Attribute) Attribute() text.Attribute {
|
|||
return text.Attribute(attr)
|
||||
}
|
||||
|
||||
// DimSuffix creates a string with the suffix dimmed.
|
||||
func DimSuffix(prefix, suffix string) text.Rich {
|
||||
return text.Rich{
|
||||
Content: prefix + suffix,
|
||||
Segments: []text.Segment{
|
||||
Segment{
|
||||
start: len(prefix),
|
||||
end: len(prefix) + len(suffix),
|
||||
attributes: Attribute(text.AttributeDimmed),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type Segment struct {
|
||||
empty.TextSegment
|
||||
start, end int
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package segments
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/state/store"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/embed"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
|
||||
_ "github.com/diamondburned/cchat-discord/internal/segments/blockquote"
|
||||
_ "github.com/diamondburned/cchat-discord/internal/segments/codeblock"
|
||||
|
@ -17,7 +17,7 @@ import (
|
|||
_ "github.com/diamondburned/cchat-discord/internal/segments/mention"
|
||||
)
|
||||
|
||||
func ParseMessage(m *discord.Message, s state.Store) text.Rich {
|
||||
func ParseMessage(m *discord.Message, s store.Cabinet) text.Rich {
|
||||
var content = []byte(m.Content)
|
||||
var node = md.ParseWithMessage(content, s, m, true)
|
||||
|
||||
|
@ -36,7 +36,7 @@ func ParseMessage(m *discord.Message, s state.Store) text.Rich {
|
|||
}
|
||||
}
|
||||
|
||||
func ParseWithMessage(b []byte, m *discord.Message, s state.Store, msg bool) text.Rich {
|
||||
func ParseWithMessage(b []byte, m *discord.Message, s store.Cabinet, msg bool) text.Rich {
|
||||
node := md.ParseWithMessage(b, s, m, msg)
|
||||
return renderer.RenderNode(b, node)
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"log"
|
||||
"testing"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/state"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/go-test/deep"
|
||||
)
|
||||
|
|
|
@ -4,14 +4,14 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/emoji"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/inline"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/segutil"
|
||||
"github.com/diamondburned/cchat-discord/internal/urlutils"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/diamondburned/ningen"
|
||||
"github.com/diamondburned/ningen/v2"
|
||||
)
|
||||
|
||||
type LargeActivityImage struct {
|
||||
|
@ -128,7 +128,7 @@ func getPresence(
|
|||
return &p.Activities[0]
|
||||
}
|
||||
|
||||
return p.Game
|
||||
return nil
|
||||
}
|
||||
|
||||
func findRole(roles []discord.Role, id discord.RoleID) (discord.Role, bool) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package mention
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"github.com/diamondburned/cchat-discord/internal/segments/renderer"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package mention
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
)
|
||||
|
|
|
@ -4,14 +4,14 @@ import (
|
|||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/state/store"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/colored"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/inline"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/segutil"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
"github.com/diamondburned/ningen"
|
||||
"github.com/diamondburned/ningen/v2"
|
||||
)
|
||||
|
||||
// NameSegment represents a clickable member name; it does not implement colors.
|
||||
|
@ -29,6 +29,7 @@ func UserSegment(start, end int, u discord.User) NameSegment {
|
|||
start: start,
|
||||
end: end,
|
||||
um: User{
|
||||
store: store.NoopCabinet,
|
||||
Member: discord.Member{User: u},
|
||||
},
|
||||
}
|
||||
|
@ -39,6 +40,7 @@ func MemberSegment(start, end int, guild discord.Guild, m discord.Member) NameSe
|
|||
start: start,
|
||||
end: end,
|
||||
um: User{
|
||||
store: store.NoopCabinet,
|
||||
Guild: guild,
|
||||
Member: m,
|
||||
},
|
||||
|
@ -48,7 +50,7 @@ func MemberSegment(start, end int, guild discord.Guild, m discord.Member) NameSe
|
|||
// WithState assigns a ningen state into the given name segment. This allows the
|
||||
// popovers to have additional information such as user notes.
|
||||
func (m *NameSegment) WithState(state *ningen.State) {
|
||||
m.um.state = state
|
||||
m.um.WithState(state)
|
||||
}
|
||||
|
||||
func (m NameSegment) Bounds() (start, end int) {
|
||||
|
@ -67,7 +69,9 @@ func (m NameSegment) AsColorer() text.Colorer {
|
|||
}
|
||||
|
||||
type User struct {
|
||||
state state.Store
|
||||
ningen *ningen.State
|
||||
store store.Cabinet
|
||||
|
||||
Guild discord.Guild
|
||||
Member discord.Member
|
||||
}
|
||||
|
@ -80,9 +84,9 @@ var (
|
|||
|
||||
// NewUser creates a new user mention. If state is of type *ningen.State, then
|
||||
// it'll fetch additional information asynchronously.
|
||||
func NewUser(state state.Store, guild discord.GuildID, guser discord.GuildUser) *User {
|
||||
func NewUser(store store.Cabinet, guild discord.GuildID, guser discord.GuildUser) *User {
|
||||
if guser.Member == nil {
|
||||
m, err := state.Member(guild, guser.ID)
|
||||
m, err := store.Member(guild, guser.ID)
|
||||
if err != nil {
|
||||
guser.Member = &discord.Member{}
|
||||
} else {
|
||||
|
@ -93,18 +97,22 @@ func NewUser(state state.Store, guild discord.GuildID, guser discord.GuildUser)
|
|||
guser.Member.User = guser.User
|
||||
|
||||
// Get the guild for the role slice. If not, then too bad.
|
||||
g, err := state.Guild(guild)
|
||||
g, err := store.Guild(guild)
|
||||
if err != nil {
|
||||
g = &discord.Guild{}
|
||||
}
|
||||
|
||||
return &User{
|
||||
state: state,
|
||||
store: store,
|
||||
Guild: *g,
|
||||
Member: *guser.Member,
|
||||
}
|
||||
}
|
||||
|
||||
func (um *User) WithState(state *ningen.State) {
|
||||
um.ningen = state
|
||||
}
|
||||
|
||||
// HasColor returns true if the current user has a color.
|
||||
func (um User) HasColor() bool {
|
||||
// We don't have any member color if we have neither the member nor guild.
|
||||
|
@ -112,7 +120,7 @@ func (um User) HasColor() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
g, err := um.state.Guild(um.Guild.ID)
|
||||
g, err := um.store.Guild(um.Guild.ID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
@ -121,7 +129,7 @@ func (um User) HasColor() bool {
|
|||
}
|
||||
|
||||
func (um User) Color() uint32 {
|
||||
g, err := um.state.Guild(um.Guild.ID)
|
||||
g, err := um.store.Guild(um.Guild.ID)
|
||||
if err != nil {
|
||||
return colored.Blurple
|
||||
}
|
||||
|
@ -190,9 +198,9 @@ func (um User) MentionInfo() text.Rich {
|
|||
|
||||
// These information can only be obtained from the state. As such, we check
|
||||
// if the state is given.
|
||||
if ningenState, ok := um.state.(*ningen.State); ok {
|
||||
if um.ningen != nil {
|
||||
// Does the user have rich presence? If so, write.
|
||||
if p, err := um.state.Presence(um.Guild.ID, um.Member.User.ID); err == nil {
|
||||
if p, err := um.store.Presence(um.Guild.ID, um.Member.User.ID); err == nil {
|
||||
for _, ac := range p.Activities {
|
||||
formatActivity(&segment, &content, ac)
|
||||
content.WriteString("\n\n")
|
||||
|
@ -200,11 +208,11 @@ func (um User) MentionInfo() text.Rich {
|
|||
} else if um.Guild.ID.IsValid() {
|
||||
// If we're still in a guild, then we can ask Discord for that
|
||||
// member with their presence attached.
|
||||
ningenState.MemberState.RequestMember(um.Guild.ID, um.Member.User.ID)
|
||||
um.ningen.MemberState.RequestMember(um.Guild.ID, um.Member.User.ID)
|
||||
}
|
||||
|
||||
// Write the user's note if any.
|
||||
if note := ningenState.NoteState.Note(um.Member.User.ID); note != "" {
|
||||
if note := um.ningen.NoteState.Note(um.Member.User.ID); note != "" {
|
||||
formatSectionf(&segment, &content, "Note")
|
||||
content.WriteRune('\n')
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package reference
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/cchat"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/cchat/utils/empty"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package renderer
|
||||
|
||||
import (
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
)
|
||||
|
||||
// InlineState assists in keeping a stateful inline segment builder.
|
||||
|
|
|
@ -3,13 +3,12 @@ package renderer
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/state"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
"github.com/diamondburned/arikawa/v2/state/store"
|
||||
"github.com/diamondburned/cchat-discord/internal/segments/segutil"
|
||||
"github.com/diamondburned/cchat/text"
|
||||
"github.com/diamondburned/ningen/md"
|
||||
"github.com/diamondburned/ningen/v2/md"
|
||||
"github.com/yuin/goldmark/ast"
|
||||
)
|
||||
|
||||
|
@ -19,7 +18,6 @@ var renderers = map[ast.NodeKind]Renderer{}
|
|||
|
||||
// Register registers a renderer to a node kind.
|
||||
func Register(kind ast.NodeKind, r Renderer) {
|
||||
log.Printf("Registering kind %v", kind)
|
||||
renderers[kind] = r
|
||||
}
|
||||
|
||||
|
@ -50,7 +48,7 @@ type Text struct {
|
|||
|
||||
// these fields can be nil
|
||||
Message *discord.Message
|
||||
Store state.Store
|
||||
Store store.Cabinet
|
||||
}
|
||||
|
||||
func New(src []byte, node ast.Node) *Text {
|
||||
|
@ -64,7 +62,7 @@ func New(src []byte, node ast.Node) *Text {
|
|||
}
|
||||
}
|
||||
|
||||
func (r *Text) WithState(m *discord.Message, s state.Store) {
|
||||
func (r *Text) WithState(m *discord.Message, s store.Cabinet) {
|
||||
r.Message = m
|
||||
r.Store = s
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/arikawa/discord"
|
||||
"github.com/diamondburned/arikawa/v2/discord"
|
||||
)
|
||||
|
||||
// AvatarURL wraps the URL with URL queries for the avatar.
|
||||
|
|
Loading…
Reference in New Issue