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

Freegle / Iznik / 11495

09 May 2026 07:35AM UTC coverage: 69.06% (-3.8%) from 72.847%
11495

Pull #408

circleci

edwh
docs(migration): mark restartproject and repaircafewales as migrated (PR #408)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pull Request #408: feat(batch): migrate check_cgas, visualise, tn_sync + dry-run improvements

9127 of 10554 branches covered (86.48%)

Branch coverage included in aggregate %.

507 of 663 new or added lines in 16 files covered. (76.47%)

11902 existing lines in 138 files now uncovered.

101630 of 149824 relevant lines covered (67.83%)

19.56 hits per line

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

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

37
const props = defineProps({
1✔
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: 'ms-1',
82
  },
83
})
84

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

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

94
const handleButtonClick = async (event) => {
1✔
95
  // Support Control+click, Cmd+click, and middle-click to open in new tab
2✔
96
  // Right-click is handled by browser context menu automatically
2✔
97
  const openInNewTab =
2✔
98
    (event && (event.ctrlKey || event.metaKey || event.button === 1)) || false
2✔
99
  await openChat(null, null, null, openInNewTab)
2✔
100
}
2✔
101

102
const gotoChat = () => {
1✔
UNCOV
103
  openChat(null, null, null)
×
UNCOV
104
}
×
105

106
const openChat = async (event, firstmessage, firstmsgid, openInNewTab) => {
1✔
107
  emit('click')
3✔
108
  console.log(
3✔
109
    'Open chat',
3✔
110
    firstmessage,
3✔
111
    firstmsgid,
3✔
112
    props.groupid,
3✔
113
    props.userid
3✔
114
  )
3✔
115

116
  if (props.groupid > 0) {
3!
UNCOV
117
    // 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
×
UNCOV
118
    // mods; if we're in MT we pass the groupid and userid and it opens from us mods to the user.
×
UNCOV
119
    const chatuserid = miscStore.modtools ? props.userid : 0
×
UNCOV
120
    const chatid = await chatStore.openChatToMods(props.groupid, chatuserid)
×
121

UNCOV
122
    if (openInNewTab && typeof window !== 'undefined' && window.open) {
×
UNCOV
123
      window.open(`/chats/${chatid}`, '_blank')
×
UNCOV
124
    } else {
×
UNCOV
125
      router.push('/chats/' + chatid)
×
UNCOV
126
    }
×
127
  } else if (props.userid > 0) {
3✔
128
    let chatid = null
3✔
129
    try {
3✔
130
      chatid = await chatStore.openChatToUser({
3✔
131
        userid: props.userid,
3✔
132
        chattype: props.chattype,
3✔
133
      })
3✔
134
    } catch (e) {
3!
UNCOV
135
      action('chat_open_failed', {
×
UNCOV
136
        error: e.message,
×
UNCOV
137
        userid: props.userid,
×
UNCOV
138
        message_id: firstmsgid,
×
UNCOV
139
      })
×
UNCOV
140
      throw e
×
UNCOV
141
    }
×
142

143
    if (chatid) {
3✔
144
      if (firstmessage) {
3!
UNCOV
145
        console.log('First message to send', firstmessage)
×
UNCOV
146
        try {
×
UNCOV
147
          await chatStore.send(chatid, firstmessage, null, null, firstmsgid)
×
UNCOV
148
          console.log('Sent')
×
149

UNCOV
150
          action('chat_message_sent', {
×
UNCOV
151
            chat_id: chatid,
×
UNCOV
152
            message_id: firstmsgid,
×
UNCOV
153
          })
×
UNCOV
154
        } catch (e) {
×
UNCOV
155
          action('chat_send_failed', {
×
UNCOV
156
            error: e.message,
×
UNCOV
157
            chat_id: chatid,
×
UNCOV
158
            message_id: firstmsgid,
×
UNCOV
159
          })
×
UNCOV
160
          throw e
×
UNCOV
161
        }
×
162

UNCOV
163
        if (firstmsgid) {
×
UNCOV
164
          // Update the message so that the reply count is updated. No need to wait.
×
UNCOV
165
          messageStore.fetch(firstmsgid, true)
×
UNCOV
166
        }
×
167

UNCOV
168
        // Refresh the message so that our reply will show.
×
UNCOV
169
        await chatStore.fetchMessages(chatid, true)
×
170

UNCOV
171
        emit('sent')
×
UNCOV
172
      }
×
173

174
      // set the flag on the store to let the chat know that a modal asking for
3✔
175
      // contact details should be opened as soon as the chat's loaded
3✔
176
      chatStore.showContactDetailsAskModal =
3✔
177
        me.value && !me.value.settings.mylocation
3✔
178

179
      // We may be called from within a profile modal. We want to skip the navigation guard which would otherwise
3✔
180
      // close the modal.
3✔
181
      if (openInNewTab) {
3✔
182
        window.open(`/chats/${chatid}`, '_blank')
1✔
183
      } else {
3✔
184
        router.push({
2✔
185
          name: 'chats-id',
2✔
186
          query: {
2✔
187
            noguard: true,
2✔
188
          },
2✔
189
          params: {
2✔
190
            id: chatid,
2✔
191
          },
2✔
192
        })
2✔
193
      }
2✔
194
    } else {
3!
UNCOV
195
      // chatid is null/undefined - log this as it means openChatToUser failed silently
×
UNCOV
196
      action('chat_open_no_chatid', {
×
UNCOV
197
        userid: props.userid,
×
UNCOV
198
        message_id: firstmsgid,
×
UNCOV
199
      })
×
UNCOV
200
    }
×
201
  }
3✔
202
}
3✔
203

204
// Expose the openChat method so it can be called from parent components
1✔
205
defineExpose({
1✔
206
  openChat,
1✔
207
})
1✔
208
</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