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

Freegle / iznik-nuxt3 / f1b2e232-33ec-457b-9de8-c38d9a34f62e

28 Nov 2025 11:02PM UTC coverage: 44.781% (+1.2%) from 43.578%
f1b2e232-33ec-457b-9de8-c38d9a34f62e

push

circleci

actions-user
Auto-merge production to app-ci-fd (daily scheduled)

Automated merge from production branch after successful tests.

🤖 Automated by GitHub Actions

3197 of 7643 branches covered (41.83%)

Branch coverage included in aggregate %.

9 of 9 new or added lines in 1 file covered. (100.0%)

112 existing lines in 11 files now uncovered.

3470 of 7245 relevant lines covered (47.9%)

12.42 hits per line

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

43.55
/components/ChatMessageText.vue
1
<template>
2
  <div
3
    class="chatMessageWrapper"
4
    :class="{ myChatMessage: messageIsFromCurrentUser }"
5
  >
6
    <div class="chatMessage forcebreak chatMessage__owner">
7
      <div>
8
        <span v-if="!highlightEmails">
9
          <span v-if="messageIsNew" class="prewrap font-weight-bold">{{
1!
10
            emessage
11
          }}</span>
12
          <span v-else class="preline forcebreak">{{ emessage }}</span>
2!
13
          <b-img
14
            v-if="chatmessage?.image"
15
            fluid
16
            :src="chatmessage?.image.path"
×
17
            lazy
18
            rounded
19
          />
20
        </span>
21
        <span v-else>
22
          <span v-if="messageIsNew" class="font-weight-bold">
×
23
            <Highlighter
24
              :text-to-highlight="emessage"
25
              :search-words="[regexEmail]"
26
              highlight-class-name="highlight"
27
              class="prewrap"
28
            />
29
          </span>
30
          <span v-else>
31
            <Highlighter
32
              :text-to-highlight="emessage"
33
              :search-words="[regexEmail]"
34
              highlight-class-name="highlight"
35
              class="preline forcebreak"
36
            />
×
37
          </span>
38
          <b-img
39
            v-if="chatmessage?.image"
40
            fluid
41
            :src="chatmessage?.image.path"
×
42
            lazy
43
            rounded
44
          />
45
        </span>
46
      </div>
47
      <div v-if="lat || lng">
1!
48
        <l-map
49
          ref="map"
50
          :zoom="16"
51
          :max-zoom="maxZoom"
52
          :center="[lat, lng]"
53
          :style="'width: 100%; height: 200px'"
54
        >
55
          <l-tile-layer :url="osmtile()" :attribution="attribution()" />
56
          <l-marker :lat-lng="[lat, lng]" :interactive="false" />
57
        </l-map>
58
        <div class="small text-muted">
59
          (Map shows approximate location of {{ postcode }})
60
        </div>
61
      </div>
62
    </div>
63
    <div class="chatMessageProfilePic">
64
      <ProfileImage
65
        :image="chatMessageProfileImage"
66
        class="ml-1 mb-1 mt-1 inline"
67
        is-thumbnail
68
        size="sm"
69
      />
70
    </div>
71
  </div>
72
</template>
73
<script setup>
74
import Highlighter from 'vue-highlight-words'
75
import { useChatMessageBase } from '~/composables/useChat'
76
import { ref, computed, onMounted } from '#imports'
77
import ProfileImage from '~/components/ProfileImage'
78
import { MAX_MAP_ZOOM, POSTCODE_REGEX } from '~/constants'
79
import { attribution, osmtile } from '~/composables/useMap'
80
import { useLocationStore } from '~/stores/location'
81

82
const props = defineProps({
1✔
83
  chatid: {
84
    type: Number,
85
    required: true,
86
  },
87
  id: {
88
    type: Number,
89
    required: true,
90
  },
91
  pov: {
92
    type: Number,
93
    required: false,
94
    default: null,
95
  },
96
  highlightEmails: {
97
    type: Boolean,
98
    required: false,
99
    default: false,
100
  },
101
})
102

103
// Use properties from ChatBase component via composable
104
const {
1✔
105
  chat,
106
  chatmessage,
107
  emessage,
108
  messageIsFromCurrentUser,
109
  chatMessageProfileImage,
110
  regexEmail,
111
} = useChatMessageBase(props.chatid, props.id, props.pov)
112

113
// Data properties
114
const lat = ref(null)
1✔
115
const lng = ref(null)
1✔
116

117
// Computed properties
118
const maxZoom = computed(() => MAX_MAP_ZOOM)
1✔
119

120
const messageIsNew = computed(() => {
1✔
121
  return (
2!
122
    chatmessage.value?.secondsago < 60 ||
2!
123
    chatmessage.value?.id > chat.value?.lastmsgseen
2!
124
  )
125
})
126

127
const postcode = computed(() => {
1✔
128
  let ret = null
1✔
129

130
  const postcodeMatch = chatmessage.value?.message.match(POSTCODE_REGEX)
1!
131

132
  if (postcodeMatch?.length) {
1!
UNCOV
133
    if (!postcodeMatch[0].includes(' ')) {
×
134
      // Make sure we have a space in the right place, because this helps with autocomplete
UNCOV
135
      ret = postcodeMatch[0].replace(/^(.*)(\d)/, '$1 $2')
×
136
    } else {
137
      ret = postcodeMatch[0]
×
138
    }
139
  }
140

141
  return ret
1✔
142
})
143

144
// Lifecycle hooks
145
onMounted(async () => {
1✔
146
  if (postcode.value) {
1!
147
    // Use typeahead to find the postcode location.
148
    const locationStore = useLocationStore()
×
UNCOV
149
    const locs = await locationStore.typeahead(postcode.value)
×
150

151
    if (locs?.length) {
×
UNCOV
152
      lat.value = locs[0].lat
×
153
      lng.value = locs[0].lng
×
154
    }
155
  }
156
})
157
</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