123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896 |
- package service
- import (
- "context"
- "errors"
- "fmt"
- "html/template"
- "mime/multipart"
- "net/url"
- "strings"
- "bloat/mastodon"
- "bloat/model"
- "bloat/renderer"
- "bloat/util"
- )
- var (
- ctx = context.Background()
- errInvalidArgument = errors.New("invalid argument")
- )
- type service struct {
- clientName string
- clientScope string
- clientWebsite string
- customCSS string
- postFormats []model.PostFormat
- renderer renderer.Renderer
- sessionRepo model.SessionRepo
- appRepo model.AppRepo
- singleInstance string
- }
- func NewService(clientName string,
- clientScope string,
- clientWebsite string,
- customCSS string,
- postFormats []model.PostFormat,
- renderer renderer.Renderer,
- sessionRepo model.SessionRepo,
- appRepo model.AppRepo,
- singleInstance string,
- ) *service {
- return &service{
- clientName: clientName,
- clientScope: clientScope,
- clientWebsite: clientWebsite,
- customCSS: customCSS,
- postFormats: postFormats,
- renderer: renderer,
- sessionRepo: sessionRepo,
- appRepo: appRepo,
- singleInstance: singleInstance,
- }
- }
- func getRendererContext(c *client) *renderer.Context {
- var settings model.Settings
- var session model.Session
- if c != nil {
- settings = c.Session.Settings
- session = c.Session
- } else {
- settings = *model.NewSettings()
- }
- return &renderer.Context{
- HideAttachments: settings.HideAttachments,
- MaskNSFW: settings.MaskNSFW,
- ThreadInNewTab: settings.ThreadInNewTab,
- FluorideMode: settings.FluorideMode,
- DarkMode: settings.DarkMode,
- CSRFToken: session.CSRFToken,
- UserID: session.UserID,
- AntiDopamineMode: settings.AntiDopamineMode,
- }
- }
- func addToReplyMap(m map[string][]mastodon.ReplyInfo, key interface{},
- val string, number int) {
- if key == nil {
- return
- }
- keyStr, ok := key.(string)
- if !ok {
- return
- }
- _, ok = m[keyStr]
- if !ok {
- m[keyStr] = []mastodon.ReplyInfo{}
- }
- m[keyStr] = append(m[keyStr], mastodon.ReplyInfo{val, number})
- }
- func (s *service) getCommonData(c *client, title string) (data *renderer.CommonData) {
- data = &renderer.CommonData{
- Title: title + " - " + s.clientName,
- CustomCSS: s.customCSS,
- }
- if c != nil && c.Session.IsLoggedIn() {
- data.CSRFToken = c.Session.CSRFToken
- }
- return
- }
- func (s *service) ErrorPage(c *client, err error) {
- var errStr string
- if err != nil {
- errStr = err.Error()
- }
- commonData := s.getCommonData(nil, "error")
- data := &renderer.ErrorData{
- CommonData: commonData,
- Error: errStr,
- }
- rCtx := getRendererContext(c)
- s.renderer.Render(rCtx, c, renderer.ErrorPage, data)
- }
- func (s *service) SigninPage(c *client) (err error) {
- commonData := s.getCommonData(nil, "signin")
- data := &renderer.SigninData{
- CommonData: commonData,
- }
- rCtx := getRendererContext(nil)
- return s.renderer.Render(rCtx, c, renderer.SigninPage, data)
- }
- func (s *service) RootPage(c *client) (err error) {
- data := &renderer.RootData{
- Title: s.clientName,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.RootPage, data)
- }
- func (s *service) NavPage(c *client) (err error) {
- u, err := c.GetAccountCurrentUser(ctx)
- if err != nil {
- return
- }
- postContext := model.PostContext{
- DefaultVisibility: c.Session.Settings.DefaultVisibility,
- DefaultFormat: c.Session.Settings.DefaultFormat,
- Formats: s.postFormats,
- }
- commonData := s.getCommonData(c, "nav")
- commonData.Target = "main"
- data := &renderer.NavData{
- User: u,
- CommonData: commonData,
- PostContext: postContext,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.NavPage, data)
- }
- func (s *service) TimelinePage(c *client, tType string, maxID string,
- minID string, instance string) (err error) {
- var nextLink, prevLink, title string
- var statuses []*mastodon.Status
- var pg = mastodon.Pagination{
- MaxID: maxID,
- MinID: minID,
- Limit: 20,
- }
- switch tType {
- default:
- return errInvalidArgument
- case "home":
- statuses, err = c.GetTimelineHome(ctx, &pg)
- title = "Timeline"
- case "direct":
- statuses, err = c.GetTimelineDirect(ctx, &pg)
- title = "Direct Timeline"
- case "local":
- statuses, err = c.GetTimelinePublic(ctx, true, &pg)
- title = "Local Timeline"
- case "twkn":
- statuses, err = c.GetTimelinePublic(ctx, false, &pg)
- title = "The Whole Known Network"
- case "remote":
- if len(instance) < 1 {
- return errInvalidArgument
- }
- var instanceURL string
- if strings.HasPrefix(instance, "https://") {
- instanceURL = instance
- instance = strings.TrimPrefix(instance, "https://")
- } else {
- instanceURL = "https://" + instance
- }
- c.Client = mastodon.NewClient(&mastodon.Config{
- Server: instanceURL,
- })
- statuses, err = c.GetTimelinePublic(ctx, true, &pg)
- title = "Remote Timeline of " + instance
- }
- if err != nil {
- return err
- }
- for i := range statuses {
- if statuses[i].Reblog != nil {
- statuses[i].Reblog.RetweetedByID = statuses[i].ID
- }
- }
- if (len(maxID) > 0 || len(minID) > 0) && len(statuses) > 0 {
- q := make(url.Values)
- q["min_id"] = []string{statuses[0].ID}
- if tType == "remote" {
- q["instance"] = []string{instance}
- }
- prevLink = fmt.Sprintf("/timeline/%s?%s", tType, q.Encode())
- }
- if len(pg.MaxID) > 0 && len(statuses) == 20 {
- q := make(url.Values)
- q["max_id"] = []string{pg.MaxID}
- if tType == "remote" {
- q["instance"] = []string{instance}
- }
- nextLink = fmt.Sprintf("/timeline/%s?%s", tType, q.Encode())
- }
- commonData := s.getCommonData(c, tType+" timeline ")
- data := &renderer.TimelineData{
- Title: title,
- Statuses: statuses,
- NextLink: nextLink,
- PrevLink: prevLink,
- CommonData: commonData,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.TimelinePage, data)
- }
- func (s *service) ThreadPage(c *client, id string, reply bool) (err error) {
- var postContext model.PostContext
- status, err := c.GetStatus(ctx, id)
- if err != nil {
- return
- }
- if reply {
- var content string
- var visibility string
- if c.Session.UserID != status.Account.ID {
- content += "@" + status.Account.Acct + " "
- }
- for i := range status.Mentions {
- if status.Mentions[i].ID != c.Session.UserID &&
- status.Mentions[i].ID != status.Account.ID {
- content += "@" + status.Mentions[i].Acct + " "
- }
- }
- isDirect := status.Visibility == "direct"
- if isDirect || c.Session.Settings.CopyScope {
- visibility = status.Visibility
- } else {
- visibility = c.Session.Settings.DefaultVisibility
- }
- postContext = model.PostContext{
- DefaultVisibility: visibility,
- DefaultFormat: c.Session.Settings.DefaultFormat,
- Formats: s.postFormats,
- ReplyContext: &model.ReplyContext{
- InReplyToID: id,
- InReplyToName: status.Account.Acct,
- ReplyContent: content,
- ForceVisibility: isDirect,
- },
- }
- }
- context, err := c.GetStatusContext(ctx, id)
- if err != nil {
- return
- }
- statuses := append(append(context.Ancestors, status), context.Descendants...)
- replies := make(map[string][]mastodon.ReplyInfo)
- idNumbers := make(map[string]int)
- for i := range statuses {
- statuses[i].ShowReplies = true
- statuses[i].IDNumbers = idNumbers
- idNumbers[statuses[i].ID] = i + 1
- statuses[i].IDReplies = replies
- addToReplyMap(replies, statuses[i].InReplyToID, statuses[i].ID, i+1)
- }
- commonData := s.getCommonData(c, "post by "+status.Account.DisplayName)
- data := &renderer.ThreadData{
- Statuses: statuses,
- PostContext: postContext,
- ReplyMap: replies,
- CommonData: commonData,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.ThreadPage, data)
- }
- func (s *service) LikedByPage(c *client, id string) (err error) {
- likers, err := c.GetFavouritedBy(ctx, id, nil)
- if err != nil {
- return
- }
- commonData := s.getCommonData(c, "likes")
- data := &renderer.LikedByData{
- CommonData: commonData,
- Users: likers,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.LikedByPage, data)
- }
- func (s *service) RetweetedByPage(c *client, id string) (err error) {
- retweeters, err := c.GetRebloggedBy(ctx, id, nil)
- if err != nil {
- return
- }
- commonData := s.getCommonData(c, "retweets")
- data := &renderer.RetweetedByData{
- CommonData: commonData,
- Users: retweeters,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.RetweetedByPage, data)
- }
- func (s *service) NotificationPage(c *client, maxID string,
- minID string) (err error) {
- var nextLink string
- var unreadCount int
- var readID string
- var excludes []string
- var pg = mastodon.Pagination{
- MaxID: maxID,
- MinID: minID,
- Limit: 20,
- }
- if c.Session.Settings.AntiDopamineMode {
- excludes = []string{"follow", "favourite", "reblog"}
- }
- notifications, err := c.GetNotifications(ctx, &pg, excludes)
- if err != nil {
- return
- }
- for i := range notifications {
- if notifications[i].Pleroma != nil && !notifications[i].Pleroma.IsSeen {
- unreadCount++
- }
- }
- if unreadCount > 0 {
- readID = notifications[0].ID
- }
- if len(notifications) == 20 && len(pg.MaxID) > 0 {
- nextLink = "/notifications?max_id=" + pg.MaxID
- }
- commonData := s.getCommonData(c, "notifications")
- commonData.RefreshInterval = c.Session.Settings.NotificationInterval
- commonData.Target = "main"
- commonData.Count = unreadCount
- data := &renderer.NotificationData{
- Notifications: notifications,
- UnreadCount: unreadCount,
- ReadID: readID,
- NextLink: nextLink,
- CommonData: commonData,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.NotificationPage, data)
- }
- func (s *service) UserPage(c *client, id string, pageType string,
- maxID string, minID string) (err error) {
- var nextLink string
- var statuses []*mastodon.Status
- var users []*mastodon.Account
- var pg = mastodon.Pagination{
- MaxID: maxID,
- MinID: minID,
- Limit: 20,
- }
- user, err := c.GetAccount(ctx, id)
- if err != nil {
- return
- }
- isCurrent := c.Session.UserID == user.ID
- switch pageType {
- case "":
- statuses, err = c.GetAccountStatuses(ctx, id, false, &pg)
- if err != nil {
- return
- }
- if len(statuses) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s?max_id=%s", id,
- pg.MaxID)
- }
- case "following":
- users, err = c.GetAccountFollowing(ctx, id, &pg)
- if err != nil {
- return
- }
- if len(users) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/following?max_id=%s",
- id, pg.MaxID)
- }
- case "followers":
- users, err = c.GetAccountFollowers(ctx, id, &pg)
- if err != nil {
- return
- }
- if len(users) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/followers?max_id=%s",
- id, pg.MaxID)
- }
- case "media":
- statuses, err = c.GetAccountStatuses(ctx, id, true, &pg)
- if err != nil {
- return
- }
- if len(statuses) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/media?max_id=%s",
- id, pg.MaxID)
- }
- case "bookmarks":
- if !isCurrent {
- return errInvalidArgument
- }
- statuses, err = c.GetBookmarks(ctx, &pg)
- if err != nil {
- return
- }
- if len(statuses) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/bookmarks?max_id=%s",
- id, pg.MaxID)
- }
- case "mutes":
- if !isCurrent {
- return errInvalidArgument
- }
- users, err = c.GetMutes(ctx, &pg)
- if err != nil {
- return
- }
- if len(users) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/mutes?max_id=%s",
- id, pg.MaxID)
- }
- case "blocks":
- if !isCurrent {
- return errInvalidArgument
- }
- users, err = c.GetBlocks(ctx, &pg)
- if err != nil {
- return
- }
- if len(users) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/blocks?max_id=%s",
- id, pg.MaxID)
- }
- case "likes":
- if !isCurrent {
- return errInvalidArgument
- }
- statuses, err = c.GetFavourites(ctx, &pg)
- if err != nil {
- return
- }
- if len(statuses) == 20 && len(pg.MaxID) > 0 {
- nextLink = fmt.Sprintf("/user/%s/likes?max_id=%s",
- id, pg.MaxID)
- }
- default:
- return errInvalidArgument
- }
- for i := range statuses {
- if statuses[i].Reblog != nil {
- statuses[i].Reblog.RetweetedByID = statuses[i].ID
- }
- }
- commonData := s.getCommonData(c, user.DisplayName)
- data := &renderer.UserData{
- User: user,
- IsCurrent: isCurrent,
- Type: pageType,
- Users: users,
- Statuses: statuses,
- NextLink: nextLink,
- CommonData: commonData,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.UserPage, data)
- }
- func (s *service) UserSearchPage(c *client,
- id string, q string, offset int) (err error) {
- var nextLink string
- var title = "search"
- user, err := c.GetAccount(ctx, id)
- if err != nil {
- return
- }
- var results *mastodon.Results
- if len(q) > 0 {
- results, err = c.Search(ctx, q, "statuses", 20, true, offset, id)
- if err != nil {
- return err
- }
- } else {
- results = &mastodon.Results{}
- }
- if len(results.Statuses) == 20 {
- offset += 20
- nextLink = fmt.Sprintf("/usersearch/%s?q=%s&offset=%d", id,
- url.QueryEscape(q), offset)
- }
- qq := template.HTMLEscapeString(q)
- if len(q) > 0 {
- title += " \"" + qq + "\""
- }
- commonData := s.getCommonData(c, title)
- data := &renderer.UserSearchData{
- CommonData: commonData,
- User: user,
- Q: qq,
- Statuses: results.Statuses,
- NextLink: nextLink,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.UserSearchPage, data)
- }
- func (s *service) AboutPage(c *client) (err error) {
- commonData := s.getCommonData(c, "about")
- data := &renderer.AboutData{
- CommonData: commonData,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.AboutPage, data)
- }
- func (s *service) EmojiPage(c *client) (err error) {
- emojis, err := c.GetInstanceEmojis(ctx)
- if err != nil {
- return
- }
- commonData := s.getCommonData(c, "emojis")
- data := &renderer.EmojiData{
- Emojis: emojis,
- CommonData: commonData,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.EmojiPage, data)
- }
- func (s *service) SearchPage(c *client,
- q string, qType string, offset int) (err error) {
- var nextLink string
- var title = "search"
- var results *mastodon.Results
- if len(q) > 0 {
- results, err = c.Search(ctx, q, qType, 20, true, offset, "")
- if err != nil {
- return err
- }
- } else {
- results = &mastodon.Results{}
- }
- if (qType == "accounts" && len(results.Accounts) == 20) ||
- (qType == "statuses" && len(results.Statuses) == 20) {
- offset += 20
- nextLink = fmt.Sprintf("/search?q=%s&type=%s&offset=%d",
- url.QueryEscape(q), qType, offset)
- }
- qq := template.HTMLEscapeString(q)
- if len(q) > 0 {
- title += " \"" + qq + "\""
- }
- commonData := s.getCommonData(c, title)
- data := &renderer.SearchData{
- CommonData: commonData,
- Q: qq,
- Type: qType,
- Users: results.Accounts,
- Statuses: results.Statuses,
- NextLink: nextLink,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.SearchPage, data)
- }
- func (s *service) SettingsPage(c *client) (err error) {
- commonData := s.getCommonData(c, "settings")
- data := &renderer.SettingsData{
- CommonData: commonData,
- Settings: &c.Session.Settings,
- PostFormats: s.postFormats,
- }
- rCtx := getRendererContext(c)
- return s.renderer.Render(rCtx, c, renderer.SettingsPage, data)
- }
- func (s *service) SingleInstance() (instance string, ok bool) {
- if len(s.singleInstance) > 0 {
- instance = s.singleInstance
- ok = true
- }
- return
- }
- func (s *service) NewSession(instance string) (rurl string, sid string, err error) {
- var instanceURL string
- if strings.HasPrefix(instance, "https://") {
- instanceURL = instance
- instance = strings.TrimPrefix(instance, "https://")
- } else {
- instanceURL = "https://" + instance
- }
- sid, err = util.NewSessionID()
- if err != nil {
- return
- }
- csrfToken, err := util.NewCSRFToken()
- if err != nil {
- return
- }
- session := model.Session{
- ID: sid,
- InstanceDomain: instance,
- CSRFToken: csrfToken,
- Settings: *model.NewSettings(),
- }
- err = s.sessionRepo.Add(session)
- if err != nil {
- return
- }
- app, err := s.appRepo.Get(instance)
- if err != nil {
- if err != model.ErrAppNotFound {
- return
- }
- mastoApp, err := mastodon.RegisterApp(ctx, &mastodon.AppConfig{
- Server: instanceURL,
- ClientName: s.clientName,
- Scopes: s.clientScope,
- Website: s.clientWebsite,
- RedirectURIs: s.clientWebsite + "/oauth_callback",
- })
- if err != nil {
- return "", "", err
- }
- app = model.App{
- InstanceDomain: instance,
- InstanceURL: instanceURL,
- ClientID: mastoApp.ClientID,
- ClientSecret: mastoApp.ClientSecret,
- }
- err = s.appRepo.Add(app)
- if err != nil {
- return "", "", err
- }
- }
- u, err := url.Parse("/oauth/authorize")
- if err != nil {
- return
- }
- q := make(url.Values)
- q.Set("scope", "read write follow")
- q.Set("client_id", app.ClientID)
- q.Set("response_type", "code")
- q.Set("redirect_uri", s.clientWebsite+"/oauth_callback")
- u.RawQuery = q.Encode()
- rurl = instanceURL + u.String()
- return
- }
- func (s *service) Signin(c *client, code string) (token string,
- userID string, err error) {
- if len(code) < 1 {
- err = errInvalidArgument
- return
- }
- err = c.AuthenticateToken(ctx, code, s.clientWebsite+"/oauth_callback")
- if err != nil {
- return
- }
- token = c.GetAccessToken(ctx)
- u, err := c.GetAccountCurrentUser(ctx)
- if err != nil {
- return
- }
- userID = u.ID
- return
- }
- func (s *service) Signout(c *client) (err error) {
- s.sessionRepo.Remove(c.Session.ID)
- return
- }
- func (s *service) Post(c *client, content string, replyToID string,
- format string, visibility string, isNSFW bool,
- files []*multipart.FileHeader) (id string, err error) {
- var mediaIDs []string
- for _, f := range files {
- a, err := c.UploadMediaFromMultipartFileHeader(ctx, f)
- if err != nil {
- return "", err
- }
- mediaIDs = append(mediaIDs, a.ID)
- }
- tweet := &mastodon.Toot{
- Status: content,
- InReplyToID: replyToID,
- MediaIDs: mediaIDs,
- ContentType: format,
- Visibility: visibility,
- Sensitive: isNSFW,
- }
- st, err := c.PostStatus(ctx, tweet)
- if err != nil {
- return
- }
- return st.ID, nil
- }
- func (s *service) Like(c *client, id string) (count int64, err error) {
- st, err := c.Favourite(ctx, id)
- if err != nil {
- return
- }
- count = st.FavouritesCount
- return
- }
- func (s *service) UnLike(c *client, id string) (count int64, err error) {
- st, err := c.Unfavourite(ctx, id)
- if err != nil {
- return
- }
- count = st.FavouritesCount
- return
- }
- func (s *service) Retweet(c *client, id string) (count int64, err error) {
- st, err := c.Reblog(ctx, id)
- if err != nil {
- return
- }
- if st.Reblog != nil {
- count = st.Reblog.ReblogsCount
- }
- return
- }
- func (s *service) UnRetweet(c *client, id string) (
- count int64, err error) {
- st, err := c.Unreblog(ctx, id)
- if err != nil {
- return
- }
- count = st.ReblogsCount
- return
- }
- func (s *service) Vote(c *client, id string, choices []string) (err error) {
- _, err = c.Vote(ctx, id, choices)
- return
- }
- func (s *service) Follow(c *client, id string, reblogs *bool) (err error) {
- _, err = c.AccountFollow(ctx, id, reblogs)
- return
- }
- func (s *service) UnFollow(c *client, id string) (err error) {
- _, err = c.AccountUnfollow(ctx, id)
- return
- }
- func (s *service) Mute(c *client, id string) (err error) {
- _, err = c.AccountMute(ctx, id)
- return
- }
- func (s *service) UnMute(c *client, id string) (err error) {
- _, err = c.AccountUnmute(ctx, id)
- return
- }
- func (s *service) Block(c *client, id string) (err error) {
- _, err = c.AccountBlock(ctx, id)
- return
- }
- func (s *service) UnBlock(c *client, id string) (err error) {
- _, err = c.AccountUnblock(ctx, id)
- return
- }
- func (s *service) Subscribe(c *client, id string) (err error) {
- _, err = c.Subscribe(ctx, id)
- return
- }
- func (s *service) UnSubscribe(c *client, id string) (err error) {
- _, err = c.UnSubscribe(ctx, id)
- return
- }
- func (s *service) SaveSettings(c *client, settings *model.Settings) (err error) {
- switch settings.NotificationInterval {
- case 0, 30, 60, 120, 300, 600:
- default:
- return errInvalidArgument
- }
- session, err := s.sessionRepo.Get(c.Session.ID)
- if err != nil {
- return
- }
- session.Settings = *settings
- return s.sessionRepo.Add(session)
- }
- func (s *service) MuteConversation(c *client, id string) (err error) {
- _, err = c.MuteConversation(ctx, id)
- return
- }
- func (s *service) UnMuteConversation(c *client, id string) (err error) {
- _, err = c.UnmuteConversation(ctx, id)
- return
- }
- func (s *service) Delete(c *client, id string) (err error) {
- return c.DeleteStatus(ctx, id)
- }
- func (s *service) ReadNotifications(c *client, maxID string) (err error) {
- return c.ReadNotifications(ctx, maxID)
- }
- func (s *service) Bookmark(c *client, id string) (err error) {
- _, err = c.Bookmark(ctx, id)
- return
- }
- func (s *service) UnBookmark(c *client, id string) (err error) {
- _, err = c.Unbookmark(ctx, id)
- return
- }
|