@@ -50,6 +50,12 @@
{{ $t('GROUP.NOTIFICATION_TYPES.' + type + '.DESCRIPTION') }}
+
-
+
diff --git a/src/group/datastore/currentGroup.js b/src/group/datastore/currentGroup.js
index 3ddcf765f1..5146ce1c29 100644
--- a/src/group/datastore/currentGroup.js
+++ b/src/group/datastore/currentGroup.js
@@ -63,9 +63,11 @@ export default {
// for current user:
membership: (state, getters, rootState, rootGetters) => getters.memberships[rootGetters['auth/userId']],
roles: (state, getters) => getters.membership ? getters.value.membership.roles : [],
+ features: state => state.current && state.current.features ? state.current.features : [],
isEditor: (state, getters) => getters.roles.includes('editor'),
isBikeKitchen: (state, getters) => Boolean(getters.value && getters.value.isBikeKitchen),
isGeneralPurpose: (state, getters) => Boolean(getters.value && getters.value.isGeneralPurpose),
+ getNotificationTypeStatus: (state, getters) => notificationType => getters['meta/status']('changeNotificationType', notificationType),
},
actions: {
...withMeta({
@@ -91,6 +93,14 @@ export default {
if (getters.id) await groups.throttledMarkUserActive(getters.id)
},
+ async trustUser ({ getters }, userId) {
+ if (!getters.id) return
+ await groups.trustUser(getters.id, userId)
+ },
+
+ }),
+
+ ...withMeta({
async changeNotificationType ({ dispatch, getters }, { notificationType, enabled }) {
if (enabled) {
await groups.addNotificationType(getters.id, notificationType)
@@ -99,12 +109,8 @@ export default {
await groups.removeNotificationType(getters.id, notificationType)
}
},
-
- async trustUser ({ getters }, userId) {
- if (!getters.id) return
- await groups.trustUser(getters.id, userId)
- },
-
+ }, {
+ findId: ({ notificationType }) => notificationType,
}),
...withPrefixedIdMeta('agreements/', {
diff --git a/src/group/pages/Settings.vue b/src/group/pages/Settings.vue
index e9cca557dd..104f523993 100644
--- a/src/group/pages/Settings.vue
+++ b/src/group/pages/Settings.vue
@@ -7,6 +7,7 @@ export default connect({
group: 'currentGroup/value',
groups: 'groups/mine',
status: 'unsubscribe/allEmailsPerGroupStatus',
+ getNotificationTypeStatus: 'currentGroup/getNotificationTypeStatus',
},
actionsToEvents: {
changeNotificationType: 'currentGroup/changeNotificationType',
diff --git a/src/locales/locale-en.json b/src/locales/locale-en.json
index 38cf5b7fd1..f519e947bd 100644
--- a/src/locales/locale-en.json
+++ b/src/locales/locale-en.json
@@ -102,7 +102,8 @@
"UNIQUE": "Name already exists, please choose another.",
"REQUIRED": "This field is required.",
"VALID_EMAIL": "Enter a valid e-mail address.",
- "VALID_TIMEZONE": "Enter a valid timezone."
+ "VALID_TIMEZONE": "Enter a valid timezone.",
+ "IMAGE_REQUIRED": "You must add an image"
},
"GROUP": {
"WALL": "Wall",
@@ -125,6 +126,7 @@
"APPLICATION_QUESTIONS": "Questions for people who want to join this group",
"PICKUPS": "Pickups",
"MESSAGES": "Messages",
+ "OFFERS": "Offers",
"PICKUP": "Pickup",
"MEMBERS": "Members",
"JOINED": "joined {relativeDate}",
@@ -166,6 +168,10 @@
"NAME": "New applications",
"DESCRIPTION": "Tells you when somebody wants to join your group"
},
+ "new_offer": {
+ "NAME": "New offers",
+ "DESCRIPTION": "Tells you when somebody creates a new offer"
+ },
"conflict_resolution": {
"NAME": "New conflict resolution processes",
"DESCRIPTION": "Tells you when a new conflict resolution process has been started in your group"
@@ -653,6 +659,23 @@
},
"NO_ONGOING": "No ongoing issues."
},
+ "OFFER": {
+ "CREATE_TITLE": "Create offer",
+ "NAME": "Name",
+ "NAME_HELPER": "Short name for the item you are offering",
+ "DESCRIPTION": "Description",
+ "MARK_AS_ACCEPTED": "Mark as accepted",
+ "MARK_AS_ACCEPTED_DESCRIPTION": "Mark this offer as accepted to show to others that it is not available any more.",
+ "MARK_AS_ARCHIVED": "Archive",
+ "MARK_AS_ARCHIVED_DESCRIPTION": "Mark this is offer as archived to remove it from the available listings.",
+ "FILTER": {
+ "STATUS": {
+ "ACTIVE": "Available",
+ "ACCEPTED": "My accepted offers",
+ "ARCHIVED": "My archived offers"
+ }
+ }
+ },
"ADDRESS_PICKER": {
"SET_AS": "Set address as",
"KEEP_EXISTING_LOCATION": "keep existing location on map",
diff --git a/src/messages/api/conversations.js b/src/messages/api/conversations.js
index 8e879a7e65..d7326ddd92 100644
--- a/src/messages/api/conversations.js
+++ b/src/messages/api/conversations.js
@@ -3,6 +3,7 @@ import { convert as convertMessage } from './messages'
import { convert as convertPickup } from '@/pickups/api/pickups'
import { convert as convertApplication } from '@/applications/api/applications'
import { convert as convertIssue } from '@/issues/api/issues'
+import { convert as convertOffer } from '@/offers/api/offers'
export default {
async get (id) {
@@ -48,6 +49,7 @@ function convertListResults (results) {
pickups: convertPickup(results.pickups),
applications: convertApplication(results.applications),
issues: convertIssue(results.issues),
+ offers: convertOffer(results.offers),
usersInfo: results.usersInfo,
meta: convertMeta(results.meta),
}
diff --git a/src/messages/components/ChatConversation.vue b/src/messages/components/ChatConversation.vue
index c4f82dce0f..99f642b578 100644
--- a/src/messages/components/ChatConversation.vue
+++ b/src/messages/components/ChatConversation.vue
@@ -1,6 +1,7 @@
diff --git a/src/messages/components/LatestConversations.vue b/src/messages/components/LatestConversations.vue
index 15113e9cbf..33193e017f 100644
--- a/src/messages/components/LatestConversations.vue
+++ b/src/messages/components/LatestConversations.vue
@@ -20,6 +20,7 @@
:place="conv.type === 'place' ? conv.target : null"
:application="conv.type === 'application' ? conv.target : null"
:issue="conv.type === 'issue' ? conv.target : null"
+ :offer="conv.type === 'offer' ? conv.target : null"
:message="conv.latestMessage"
:unread-count="conv.unreadMessageCount"
:muted="conv.muted"
@@ -115,6 +116,11 @@ export default {
case 'private': return this.openForUser(target)
case 'application': return this.openForApplication(target)
case 'issue': return this.$router.push({ name: 'issueChat', params: { groupId: target.group.id, issueId: target.id } }).catch(() => {})
+ case 'offer': return this.$router.push({
+ name: 'offerDetail',
+ params: { groupId: target.group.id, offerId: target.id },
+ query: this.$route.query,
+ }).catch(() => {})
}
},
isSelected (conv) {
diff --git a/src/messages/components/LatestMessageItem.vue b/src/messages/components/LatestMessageItem.vue
index 398d6225c7..7965c69d00 100644
--- a/src/messages/components/LatestMessageItem.vue
+++ b/src/messages/components/LatestMessageItem.vue
@@ -78,6 +78,16 @@
{{ issue.affectedUser && issue.affectedUser.displayName }}
+
+
+
+ {{ offer.name }}
+
+
pickupId => getters.getForType('pickup', pickupId),
getForApplication: (state, getters) => applicationId => getters.getForType('application', applicationId),
getForIssue: (state, getters) => issueId => getters.getForType('issue', issueId),
+ getForOffer: (state, getters) => offerId => getters.getForType('offer', offerId),
getForUser: (state, getters) => userId => {
const { id } = Object.values(state.entries).find(({ type, participants }) => type === 'private' && participants.includes(userId)) || {}
if (!id) return
@@ -189,6 +191,7 @@ export default {
case 'pickup': return rootGetters['pickups/get'](targetId)
case 'application': return rootGetters['applications/get'](targetId)
case 'issue': return rootGetters['issues/get'](targetId)
+ case 'offer': return rootGetters['latestMessages/getRelated']('offer', targetId)
case 'private': return participants.find(u => !u.isCurrentUser)
}
},
@@ -351,6 +354,15 @@ export default {
dispatch('fetch', conversation.id)
},
+ async fetchForOffer ({ commit, getters, dispatch }, { offerId }) {
+ let conversation = getters.getForOffer(offerId)
+ if (!conversation) {
+ conversation = await offersAPI.conversation(offerId)
+ commit('setConversation', conversation)
+ }
+ dispatch('fetch', conversation.id)
+ },
+
clearForIssue ({ getters, commit }, { issueId }) {
const { id: conversationId } = getters.getForIssue(issueId) || {}
if (conversationId) commit('clearMessages', conversationId)
diff --git a/src/messages/datastore/latestMessages.js b/src/messages/datastore/latestMessages.js
index 66b45a53ee..8cf6c64623 100644
--- a/src/messages/datastore/latestMessages.js
+++ b/src/messages/datastore/latestMessages.js
@@ -10,6 +10,7 @@ function initialState () {
conversationMessages: {},
threads: {},
threadMessages: {},
+ related: {}, // -> { ->