• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Freegle / iznik-nuxt3 / 03b7ce59-0b72-4c64-ad83-a68e43b55ee7

09 Feb 2026 06:31PM UTC coverage: 43.797% (-0.3%) from 44.143%
03b7ce59-0b72-4c64-ad83-a68e43b55ee7

Pull #165

circleci

edwh
feat: Switch NoticeboardAPI write methods to v2

Switch add(), save(), and action() from $post/$patch to $postv2/$patchv2.
Also removes console.log from add().

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pull Request #165: feat: Switch NoticeboardAPI writes to v2

3745 of 8748 branches covered (42.81%)

Branch coverage included in aggregate %.

1706 of 3698 relevant lines covered (46.13%)

82.35 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.75
/components/ChatButton.vue
1
<template>
2
  <div v-if="userid !== myid" class="d-inline clickme">
145!
3
    <slot>
4
      <b-button
5
        :size="size"
6
        :variant="variant"
7
        :class="btnClass + ' d-none d-sm-inline'"
8
        @click="gotoChat(true)"
130✔
9
      >
10
        <v-icon v-if="showIcon" icon="comments" />
69!
11
        <span v-if="title" :class="titleClass">
69✔
12
          {{ title }}
13
        </span>
14
      </b-button>
15
      <b-button
16
        :size="size"
17
        :variant="variant"
18
        :class="btnClass + ' d-inline-block d-sm-none'"
19
        @click="gotoChat(false)"
130✔
20
      >
21
        <v-icon v-if="showIcon" icon="comments" />
69!
22
        <span v-if="title" :class="titleClass">
69✔
23
          {{ title }}
24
        </span>
25
      </b-button>
26
    </slot>
27
  </div>
28
</template>
29
<script setup>
30
import { useChatStore } from '~/stores/chat'
31
import { useMessageStore } from '~/stores/message'
32
import { useMiscStore } from '~/stores/misc'
33
import { useRouter } from '#imports'
34
import { useMe } from '~/composables/useMe'
35
import { action } from '~/composables/useClientLog'
36

37
const props = defineProps({
83✔
38
  size: {
39
    type: String,
40
    required: false,
41
    default: null,
42
  },
43
  title: {
44
    type: String,
45
    required: false,
46
    default: null,
47
  },
48
  variant: {
49
    type: String,
50
    required: false,
51
    default: 'primary',
52
  },
53
  groupid: {
54
    type: Number,
55
    required: false,
56
    default: null,
57
  },
58
  userid: {
59
    type: Number,
60
    required: false,
61
    default: null,
62
  },
63
  chattype: {
64
    type: String,
65
    required: false,
66
    default: null,
67
  },
68
  showIcon: {
69
    type: Boolean,
70
    required: false,
71
    default: true,
72
  },
73
  btnClass: {
74
    type: String,
75
    required: false,
76
    default: null,
77
  },
78
  titleClass: {
79
    type: String,
80
    required: false,
81
    default: 'ml-1',
82
  },
83
})
84

85
const emit = defineEmits(['click', 'sent'])
86
const chatStore = useChatStore()
87
const messageStore = useMessageStore()
88
const miscStore = useMiscStore()
89
const router = useRouter()
90

91
// Use me and myid computed properties from useMe composable for consistency
92
const { me, myid } = useMe()
93

94
const gotoChat = () => {
95
  openChat(null, null, null)
×
96
}
97

98
const openChat = async (event, firstmessage, firstmsgid) => {
99
  emit('click')
100
  console.log(
101
    'Open chat',
102
    firstmessage,
103
    firstmsgid,
104
    props.groupid,
105
    props.userid
106
  )
107

108
  if (props.groupid > 0) {
19!
109
    // Open a chat to the mods. If we are in FD then we just pass the group id and the chat opens from us to the
110
    // mods; if we're in MT we pass the groupid and userid and it opens from us mods to the user.
111
    const chatuserid = miscStore.modtools ? props.userid : 0
×
112
    const chatid = await chatStore.openChatToMods(props.groupid, chatuserid)
113

114
    router.push('/chats/' + chatid)
×
115
  } else if (props.userid > 0) {
19!
116
    let chatid = null
19✔
117
    try {
19✔
118
      chatid = await chatStore.openChatToUser({
19✔
119
        userid: props.userid,
120
        chattype: props.chattype,
121
      })
122
    } catch (e) {
123
      action('chat_open_failed', {
×
124
        error: e.message,
125
        userid: props.userid,
126
        message_id: firstmsgid,
127
      })
128
      throw e
129
    }
130

131
    if (chatid) {
19!
132
      if (firstmessage) {
19!
133
        console.log('First message to send', firstmessage)
19✔
134
        try {
19✔
135
          await chatStore.send(chatid, firstmessage, null, null, firstmsgid)
19✔
136
          console.log('Sent')
137

138
          action('chat_message_sent', {
139
            chat_id: chatid,
140
            message_id: firstmsgid,
141
          })
142
        } catch (e) {
143
          action('chat_send_failed', {
×
144
            error: e.message,
145
            chat_id: chatid,
146
            message_id: firstmsgid,
147
          })
148
          throw e
149
        }
150

151
        if (firstmsgid) {
19✔
152
          // Update the message so that the reply count is updated. No need to wait.
153
          messageStore.fetch(firstmsgid, true)
154
        }
155

156
        // Refresh the message so that our reply will show.
157
        await chatStore.fetchMessages(chatid, true)
158

159
        emit('sent')
160
      }
161

162
      // set the flag on the store to let the chat know that a modal asking for
163
      // contact details should be opened as soon as the chat's loaded
164
      chatStore.showContactDetailsAskModal =
19✔
165
        me.value && !me.value.settings.mylocation
38✔
166

167
      // We may be called from within a profile modal. We want to skip the navigation guard which would otherwise
168
      // close the modal.
169
      router.push({
170
        name: 'chats-id',
171
        query: {
172
          noguard: true,
173
        },
174
        params: {
175
          id: chatid,
176
        },
177
      })
178
    } else {
179
      // chatid is null/undefined - log this as it means openChatToUser failed silently
180
      action('chat_open_no_chatid', {
×
181
        userid: props.userid,
182
        message_id: firstmsgid,
183
      })
184
    }
185
  }
186
}
187

188
// Expose the openChat method so it can be called from parent components
189
defineExpose({
190
  openChat,
191
})
192
</script>
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc