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

Freegle / iznik-nuxt3 / 9852a904-8759-432a-8699-8a8ec6be5344

27 Jan 2026 08:37PM UTC coverage: 44.873% (+1.5%) from 43.401%
9852a904-8759-432a-8699-8a8ec6be5344

push

circleci

CircleCI Auto-merge
Auto-merge master to production after successful tests - Original commit: copy: Update wanted post description to emphasize community

3683 of 8367 branches covered (44.02%)

Branch coverage included in aggregate %.

1678 of 3580 relevant lines covered (46.87%)

111.82 hits per line

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

0.0
/components/ChatMessageModMail.vue
1
<template>
2
  <div>
3
    <b-row>
4
      <b-col>
5
        <div class="media">
6
          <b-card border-variant="success" :class="{ 'ml-auto': !amUser }">
7
            <b-card-title>
8
              <div v-if="group">
×
9
                <h4>
10
                  <ProfileImage
11
                    v-if="group"
×
12
                    :image="group.profile"
13
                    class="mr-1 mb-1 mt-1 inline"
14
                    is-thumbnail
15
                    size="sm"
16
                  />
17
                  <span class="align-middle">
18
                    Message from {{ group.namedisplay }} Volunteers
19
                  </span>
20
                </h4>
21
              </div>
22
              <h4 v-else>Message from Freegle Volunteers</h4>
23
              <div v-if="realMod" class="text-muted small">
×
24
                <div class="small">
25
                  (Sent by
26
                  <v-icon icon="hashtag" class="text-muted" scale="0.5" />{{
27
                    chatmessage.userid
28
                  }})
29
                </div>
30
              </div>
31
            </b-card-title>
32
            <b-card-text>
33
              <div :class="emessage ? 'media-body chatMessage' : 'media-body'">
×
34
                <span>
35
                  <span
36
                    v-if="
×
37
                      chatmessage.secondsago < 60 ||
38
                      chatmessage.id > chat.lastmsgseen
39
                    "
40
                    class="prewrap font-weight-bold"
41
                    >{{ emessage }}</span
42
                  >
43
                  <span v-else class="preline forcebreak">{{ emessage }}</span>
44
                  <b-img
45
                    v-if="chatmessage.image"
×
46
                    fluid
47
                    :src="chatmessage.image.path"
48
                    lazy
49
                    rounded
50
                  />
51
                </span>
52
              </div>
53
              <div v-if="chatmessage.refmsgid && refmsg">
×
54
                <hr />
55
                <p>
×
56
                  If you have been asked to edit and resend this message, you
57
                  can do so here:
58
                </p>
59
                <b-button variant="warning" @click="repost">
60
                  <v-icon icon="pen" /> Edit and Resend
×
61
                </b-button>
62
              </div>
63
              <NoticeMessage
64
                v-else-if="chat.chattype === 'User2User'"
65
                variant="warning"
66
                class="mt-2"
67
              >
68
                <p>
×
69
                  Volunteers won't see any replies you make in here about this
70
                  message - they'll go to the other freegler. If you want to
71
                  contact the volunteers, please use the button below.
72
                </p>
73
                <GroupSelect
74
                  v-model="contactGroupId"
75
                  remember="contactmods"
76
                  class="mb-3"
77
                />
78
                <ChatButton
79
                  :groupid="contactGroupId"
80
                  size="md"
81
                  title="Contact community volunteers"
82
                  variant="primary"
83
                  class="mb-2"
84
                />
85
              </NoticeMessage>
86
            </b-card-text>
87
          </b-card>
88
        </div>
89
      </b-col>
90
    </b-row>
91
  </div>
92
</template>
93
<script setup>
94
import { ref, computed } from 'vue'
95
import NoticeMessage from './NoticeMessage'
96
import ChatButton from './ChatButton'
97
import { useComposeStore } from '~/stores/compose'
98
import {
99
  fetchReferencedMessage,
100
  useChatMessageBase,
101
} from '~/composables/useChat'
102
import ProfileImage from '~/components/ProfileImage'
103
import GroupSelect from '~/components/GroupSelect'
104
import { useRouter } from '#imports'
105

106
const props = defineProps({
×
107
  chatid: {
108
    type: Number,
109
    required: true,
110
  },
111
  id: {
112
    type: Number,
113
    required: true,
114
  },
115
  last: {
116
    type: Boolean,
117
    required: false,
118
    default: false,
119
  },
120
  pov: {
121
    type: Number,
122
    required: false,
123
    default: null,
124
  },
125
  highlightEmails: {
126
    type: Boolean,
127
    required: false,
128
    default: false,
129
  },
130
})
131

132
// Use the chat base composable
133
const { chat, chatmessage, emessage, refmsg, me, myid, realMe } =
134
  useChatMessageBase(props.chatid, props.id, props.pov)
135

136
const composeStore = useComposeStore()
137
const contactGroupId = ref(null)
138

139
// Setup
140
await fetchReferencedMessage(props.chatid, props.id)
×
141

142
const group = computed(() => {
×
143
  return chat.value && chat.value.group ? chat.value.group : null
×
144
})
145

146
const amUser = computed(() => {
147
  return chat.value && chat.value.user && chat.value.user.id === myid
×
148
})
149

150
const realMod = computed(() => {
151
  // Show "(Sent by #...)" to moderators, support, and admins
152
  return (
153
    realMe.value &&
×
154
    (realMe.value.systemrole === 'Moderator' ||
155
      realMe.value.systemrole === 'Support' ||
156
      realMe.value.systemrole === 'Admin')
157
  )
158
})
159

160
async function repost() {
×
161
  const message = Object.assign({}, refmsg.value)
×
162

163
  if (message) {
×
164
    // Remove any partially composed messages we currently have, because they'll be confusing.
165
    await composeStore.clearMessages()
166

167
    // Add this message to the compose store so that it will show up on the compose page.
168
    await composeStore.setMessage(
169
      0,
170
      {
171
        type: message.type,
172
        item: message.item?.name?.trim(),
×
173
        description: message.textbody.trim(),
174
        availablenow: message.availablenow,
175
        repostof: chatmessage.value.refmsgid,
176
      },
177
      me.value
178
    )
179

180
    composeStore.setAttachmentsForMessage(0, message.attachments)
181

182
    const router = useRouter()
183
    router.push(message.type === 'Offer' ? '/give' : '/find')
×
184
  }
185
}
186
</script>
187
<style scoped lang="scss">
188
.chatMessage {
189
  border: 1px solid $color-gray--light;
190
  border-radius: 10px;
191
  padding-top: 2px;
192
  padding-bottom: 2px;
193
  padding-left: 4px;
194
  padding-right: 2px;
195
  word-wrap: break-word;
196
  line-height: 1.5;
197
}
198
</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