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

Freegle / iznik-nuxt3 / ce5abe40-6f99-4088-a6e7-20c39d0d906f

28 Nov 2025 03:32PM UTC coverage: 43.578% (-2.3%) from 45.902%
ce5abe40-6f99-4088-a6e7-20c39d0d906f

push

circleci

edwh
Fix TestFlight version to be higher than production (99.0.x) and force update plugin

3135 of 7742 branches covered (40.49%)

Branch coverage included in aggregate %.

3417 of 7293 relevant lines covered (46.85%)

12.25 hits per line

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

0.0
/components/ChatMessagePromised.vue
1
<template>
2
  <div class="clearfix">
×
3
    <div v-if="chatmessage?.userid != myid" class="media">
4
      <div v-if="!refmsg">
5
        This chat message refers to a post (<v-icon
6
          icon="hashtag"
7
          class="text-muted fa-0-8x"
8
        />{{ chatmessage.refmsgid }}) which has been deleted.
9
      </div>
10
      <b-card v-else border-variant="success" class="ml-2">
11
        <b-card-title>
12
          <nuxt-link
13
            no-prefetch
14
            :to="
15
              (messageIsFromCurrentUser ? '/mypost/' : '/message/') + refmsgid
16
            "
17
          >
18
            <b-img
19
              v-if="refmsg?.attachments?.length > 0"
20
              class="float-end ml-1"
21
              rounded
22
              thumbnail
23
              generator-unable-to-provide-required-alt=""
24
              lazy
25
              :src="refmsg.attachments[0].paththumb"
26
              width="70px"
27
              @error="brokenImage"
28
            />
29
          </nuxt-link>
×
30
          <ProfileImage
31
            :image="otheruser.profile.paththumb"
×
32
            class="mr-1 mb-1 mt-1 inline"
33
            is-thumbnail
34
            size="sm"
35
          />
36
          <span class="small black">Good news! You've been promised this:</span>
37
          <br />
×
38
          <nuxt-link
39
            no-prefetch
40
            :to="
41
              (messageIsFromCurrentUser ? '/mypost/' : '/message/') + refmsgid
42
            "
43
          >
44
            <h4>
45
              {{ refmsg?.subject }}
46
            </h4>
47
          </nuxt-link>
48
          <AddToCalendar
49
            v-if="tryst?.calendarLink"
×
50
            :calendar-link="tryst.calendarLink"
×
51
            class="mr-2"
52
          />
53
          <notice-message
54
            v-if="refmsg.outcomes?.length || refmsg.deleted"
55
            class="mt-2 mb-2"
×
56
          >
57
            <v-icon icon="info-circle" />
58
            <span v-if="refmsg.type === 'Offer'">
59
              This is no longer available.
60
            </span>
61
            <span v-else> They are no longer looking for this. </span>
62
          </notice-message>
×
63
        </b-card-title>
64
        <b-card-text>
65
          <div :class="emessage ? 'media-body chatMessage' : 'media-body'">
×
66
            <span>
67
              <span
68
                v-if="
69
                  chatmessage.secondsago < 60 ||
70
                  chatmessage.id > chat.lastmsgseen
71
                "
72
                class="prewrap font-weight-bold"
73
                >{{ emessage }}</span
74
              >
×
75
              <span v-else class="preline forcebreak">{{ emessage }}</span>
76
              <b-img
77
                v-if="chatmessage.image"
78
                fluid
79
                :src="chatmessage.image.path"
80
                lazy
81
                rounded
82
              />
83
            </span>
84
          </div>
85
        </b-card-text>
86
      </b-card>
87
    </div>
88
    <div v-else class="media float-end">
89
      <div v-if="!refmsg">
90
        This chat message refers to a post (<v-icon
91
          icon="hashtag"
92
          class="text-muted fa-0-8x"
93
        />{{ chatmessage.refmsgid }}) which has been deleted.
94
      </div>
95
      <b-card v-else border-variant="success">
96
        <b-card-title>
97
          <nuxt-link
98
            no-prefetch
99
            :to="
100
              (messageIsFromCurrentUser ? '/mypost/' : '/message/') + refmsgid
101
            "
×
102
          >
103
            <b-img
104
              v-if="refmsg && refmsg.attachments?.length > 0"
105
              class="float-end"
106
              rounded
107
              thumbnail
108
              generator-unable-to-provide-required-alt=""
109
              lazy
110
              :src="refmsg.attachments[0].paththumb"
111
              width="70px"
×
112
              @error="brokenImage"
113
            />
114
          </nuxt-link>
×
115
          <div class="d-flex justify-content-start align-items-center">
116
            <ProfileImage
117
              :image="me.profile.path"
118
              class="mr-1 inline"
119
              is-thumbnail
120
              size="sm"
121
            />
×
122
            <div class="small black">
123
              You promised <strong>{{ otheruser.displayname }}</strong
124
              >:
125
            </div>
126
          </div>
127
          <nuxt-link
128
            no-prefetch
129
            :to="
130
              (messageIsFromCurrentUser ? '/mypost/' : '/message/') + refmsgid
131
            "
132
            class="nodecor"
133
          >
134
            <h4>
135
              {{ refmsg?.subject }}
136
            </h4>
137
          </nuxt-link>
138
          <p v-if="tryst?.arrangedfor" class="small text-info">
139
            Handover arranged for
140
            <strong
141
              ><DateFormatted :value="tryst.arrangedfor" format="weekdaytime"
142
            /></strong>
143
          </p>
144
          <div
145
            v-if="refmsg"
146
            class="d-flex mt-1 flex-wrap justify-content-between"
×
147
          >
148
            <template v-if="tryst">
149
              <AddToCalendar
×
150
                v-if="tryst?.calendarLink"
151
                :calendar-link="tryst.calendarLink"
152
                class="mr-2 mb-1"
153
              />
154
              <b-button
×
155
                v-if="refmsg.promisecount && refmsg.availablenow"
156
                variant="secondary"
157
                class="mr-2 mb-1"
158
                @click="changeTime"
159
              >
160
                <v-icon icon="pen" />
161
                Change time
162
              </b-button>
163
            </template>
164
            <template v-else-if="refmsg.promisecount && refmsg.availablenow">
×
165
              <b-button
166
                variant="secondary"
167
                class="mr-2 mb-1"
168
                @click="changeTime"
169
              >
×
170
                <v-icon icon="pen" />
171
                Set time
172
              </b-button>
173
            </template>
174
            <b-button
175
              v-if="refmsg.promisecount && refmsg.availablenow"
×
176
              variant="warning"
177
              class="align-middle mr-2 mb-1"
178
              @click="unpromise"
179
            >
180
              Unpromise
×
181
            </b-button>
182
            <b-button
183
              v-if="refmsg.availablenow"
×
184
              variant="primary"
185
              class="mr-1 mb-1"
186
              @click="outcome('Taken')"
×
187
            >
188
              Mark as TAKEN
189
            </b-button>
×
190
          </div>
×
191
          <PromiseModal
×
192
            v-if="showPromise"
193
            :messages="[refmsg]"
194
            :selected-message="refmsgid"
195
            :users="otheruser ? [otheruser] : []"
×
196
            :selected-user="otheruser ? otheruser.id : null"
197
            @hidden="showPromise = false"
198
          />
×
199
        </b-card-title>
200
        <b-card-text>
201
          <div :class="emessage ? 'media-body chatMessage' : 'media-body'">
202
            <span>
203
              <span
204
                v-if="
205
                  chatmessage.secondsago < 60 ||
206
                  chatmessage.id > chat.lastmsgseen
207
                "
×
208
                class="prewrap font-weight-bold"
209
                >{{ emessage }}</span
210
              >
211
              <span v-else class="preline forcebreak">{{ emessage }}</span>
212
              <b-img
213
                v-if="chatmessage.image"
214
                fluid
×
215
                :src="chatmessage.image.path"
×
216
                lazy
217
                rounded
218
              />
219
            </span>
220
          </div>
221
          <p v-if="!refmsg?.availablenow" class="text-muted">
222
            This has now been taken.
×
223
          </p>
224
        </b-card-text>
225
      </b-card>
226
    </div>
227
    <RenegeModal
228
      v-if="showRenege && refmsgid"
×
229
      :messages="[refmsgid]"
230
      :selected-message="refmsgid"
231
      :users="[otheruser]"
×
232
      :selected-user="otheruser.id"
233
      @hide="fetchMessages"
234
      @hidden="showRenege = false"
235
    />
236
    <OutcomeModal
×
237
      v-if="showOutcome && refmsgid"
238
      :id="refmsgid"
239
      :taken-by="takenBy"
240
      :type="outcomeType"
241
      @outcome="fetchMessage"
242
      @hidden="showOutcome = false"
243
    />
244
  </div>
245
</template>
246
<script setup>
247
import { ref, defineAsyncComponent } from 'vue'
248
import DateFormatted from './DateFormatted'
249
import { useTrystStore } from '~/stores/tryst'
250
import { fetchOurOffers } from '~/composables/useThrottle'
251
import { useChatStore } from '~/stores/chat'
252
import {
253
  fetchReferencedMessage,
254
  useChatMessageBase,
×
255
} from '~/composables/useChat'
256
import { useMessageStore } from '~/stores/message'
257
import AddToCalendar from '~/components/AddToCalendar'
258
import ProfileImage from '~/components/ProfileImage'
×
259

×
260
const OutcomeModal = defineAsyncComponent(() =>
261
  import('~/components/OutcomeModal')
262
)
263

×
264
const RenegeModal = defineAsyncComponent(() => import('./RenegeModal'))
265
const PromiseModal = defineAsyncComponent(() =>
266
  import('~/components/PromiseModal')
267
)
268

269
const props = defineProps({
270
  chatid: {
271
    type: Number,
272
    required: true,
273
  },
274
  id: {
275
    type: Number,
276
    required: true,
277
  },
278
  last: {
279
    type: Boolean,
280
    required: false,
281
    default: false,
282
  },
283
  pov: {
284
    type: Number,
285
    required: false,
286
    default: null,
287
  },
288
  highlightEmails: {
289
    type: Boolean,
290
    required: false,
×
291
    default: false,
×
292
  },
×
293
})
×
294

295
// Data properties
296
const showRenege = ref(false)
×
297
const showOutcome = ref(false)
×
298
const outcomeType = ref(null)
×
299
const showPromise = ref(false)
300

301
// Stores
×
302
const trystStore = useTrystStore()
×
303
const chatStore = useChatStore()
304
const messageStore = useMessageStore()
305

×
306
// Setup
307
await trystStore.fetch()
308
await fetchReferencedMessage(props.chatid, props.id)
309

310
// Use the chat base composable
311
const {
312
  chat,
313
  chatmessage,
314
  emessage,
315
  messageIsFromCurrentUser,
316
  refmsgid,
317
  refmsg,
318
  me,
319
  myid,
×
320
  otheruser,
×
321
  brokenImage,
322
  fetchMessage,
323
} = useChatMessageBase(props.chatid, props.id, props.pov)
324

×
325
if (refmsgid.value) {
×
326
  useMessageStore().fetch(refmsgid.value)
327
}
328

×
329
// Component-specific computed properties
×
330
const tryst = computed(() => {
331
  return otheruser.value ? trystStore?.getByUser(otheruser.value.id) : null
×
332
})
×
333

×
334
const takenBy = computed(() => {
×
335
  let ret = null
336

337
  if (otheruser.value) {
×
338
    ret = otheruser.value
339
    ret.userid = otheruser.value.id
340
    ret.count = 1
341
  }
×
342

×
343
  return ret
×
344
})
345

346
// Methods
×
347
function unpromise() {
×
348
  showRenege.value = true
349
  fetchOurOffers()
350
}
×
351

×
352
function changeTime() {
353
  showPromise.value = true
354
}
×
355

×
356
function fetchMessages() {
357
  chatStore.fetchMessages(chatmessage.value.chatid)
×
358
}
×
359

360
async function outcome(type) {
361
  await messageStore.fetch(refmsgid.value)
362

363
  showOutcome.value = true
364
  outcomeType.value = type
365
}
366
</script>
367
<style scoped lang="scss">
368
.chatMessage {
369
  border: 1px solid $color-gray--light;
370
  border-radius: 10px;
371
  padding-top: 2px;
372
  padding-bottom: 2px;
373
  padding-left: 4px;
374
  padding-right: 2px;
375
  word-wrap: break-word;
376
  line-height: 1.5;
377
}
378
</style>
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