Skip to content

Commit 1d6d626

Browse files
Resul AvanResul Avan
Resul Avan
authored and
Resul Avan
committed
share on social buttons
1 parent dbeefc6 commit 1d6d626

20 files changed

+280
-34
lines changed

.circleci/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ jobs:
4343
echo "})" >> src/static/firebase-messaging-sw.js
4444
echo "" >> src/static/firebase-messaging-sw.js
4545
- run:
46-
name: deploy to Firebase Hosting
46+
name: deploy to Firebase Hosting&Functions
4747
command: ./src/node_modules/.bin/firebase deploy --project=$FIREBASE_PROJECT_ID --token=$FIREBASE_CI_TOKEN
4848
- run:
4949
name: Call to warm up

functions/modules/handlers-module/src/api/api-handler.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
getTokenFromRequest,
66
handleApiErrors,
77
handlerCalledLog
8-
} from '../service/request-handler-service';
8+
} from '../service/request-handler-service'
99
import { getDecodedIdToken } from '../service/firebase-admin-service'
1010
import { ApiErrorCode } from 'types-module'
1111
import DecodedIdToken = admin.auth.DecodedIdToken

functions/modules/handlers-module/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"forceConsistentCasingInFileNames": true,
1313
"resolveJsonModule": true,
1414
"types": [
15-
"./src/types"
15+
"./src/types",
16+
"types-module"
1617
]
1718
},
1819
"include": [

functions/src/apiApp.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import cookieParser from 'cookie-parser'
33
import { json } from 'body-parser'
44
import cors from 'cors'
55
import { RuntimeOptions, runWith } from 'firebase-functions'
6-
import { ApiConfig } from 'types-module';
6+
import { ApiConfig } from 'types-module'
77
import {
88
claimsHandler,
99
extractHeaderHandler,

functions/src/sitemapApp.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import express, { Router } from 'express'
2-
32
import { RuntimeOptions, runWith } from "firebase-functions"
43
import { sitemapHandler } from 'handlers-module'
54

functions/tsconfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
"resolveJsonModule": true,
1212
"esModuleInterop": true,
1313
"types": [
14-
"./src/types"
14+
"./src/types",
15+
"types-module",
16+
"handlers-module"
1517
]
1618
},
1719
"compileOnSave": true,

src/assets/main.scss

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@import './variables.scss';
2+
// Import buefy and bulma styles
3+
@import "~bulma";
4+
@import "~buefy/src/scss/buefy";
5+
// Import your other app styles
6+
//@import "./style.css";

src/assets/style.scss

-1
This file was deleted.

src/assets/variables.scss

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
@import "~bulma/sass/utilities/_all";
2+
3+
$primary: #8c67ef;
4+
$primary-invert: findColorInvert($primary);
5+
6+
$twitter: #55acee;
7+
$twitter-invert: findColorInvert($twitter);
8+
9+
$facebook: #3b5999;
10+
$facebook-invert: findColorInvert($facebook);
11+
12+
$whatsapp: #25D366;
13+
$whatsapp-invert: findColorInvert($whatsapp);
14+
15+
$pinterest: #bd081c;
16+
$pinterest-invert: findColorInvert($pinterest);
17+
18+
$colors: (
19+
"white": ($white, $black),
20+
"black": ($black, $white),
21+
"light": ($light, $light-invert),
22+
"dark": ($dark, $dark-invert),
23+
"primary": ($primary, $primary-invert),
24+
"info": ($info, $info-invert),
25+
"success": ($success, $success-invert),
26+
"warning": ($warning, $warning-invert),
27+
"danger": ($danger, $danger-invert),
28+
"twitter": ($twitter, $twitter-invert),
29+
"facebook": ($facebook, $facebook-invert),
30+
"whatsapp": ($whatsapp, $whatsapp-invert),
31+
"pinterest": ($pinterest, $pinterest-invert)
32+
);

src/components/navbar/LanguageSwitcher.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<b-navbar-dropdown :boxed="true" :close-on-click="true" :arrowless="true">
2+
<b-navbar-dropdown :boxed="true" :close-on-click="true" :arrowless="true" right>
33
<template slot="label">
44
<img class="image-fit-cover square-28" :src="activeLanguage.flag.src" :alt="activeLanguage.flag.alt">
55
</template>

src/components/navbar/ProfileNavigator.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<b-navbar-dropdown :boxed="true" :close-on-click="true" :arrowless="true">
2+
<b-navbar-dropdown :boxed="true" :close-on-click="true" :arrowless="true" right>
33
<template slot="label">
44
<b-icon
55
icon="chevron-down"

src/components/navbar/TopImage.vue

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<template>
2+
<b-navbar-dropdown :boxed="true" :close-on-click="true" :arrowless="true" right>
3+
<template slot="label">
4+
<span>Images</span>
5+
<b-icon
6+
icon="chevron-down"
7+
size="is-small"
8+
/>
9+
</template>
10+
11+
<b-navbar-item
12+
:to="routes.LIGHT_BOX"
13+
tag="router-link"
14+
>
15+
{{ $t('topNavbar.lightbox') }}
16+
</b-navbar-item>
17+
18+
<b-navbar-item
19+
:to="routes.CROP"
20+
tag="router-link"
21+
>
22+
{{ $t('topNavbar.crop') }}
23+
</b-navbar-item>
24+
25+
<b-navbar-item
26+
:to="routes.IMAGES"
27+
tag="router-link"
28+
>
29+
{{ $t('topNavbar.images') }}
30+
</b-navbar-item>
31+
</b-navbar-dropdown>
32+
</template>
33+
34+
<script lang="ts">
35+
import { Component, Vue } from 'nuxt-property-decorator'
36+
import SocialShare from '~/components/ui/social/SocialShare.vue'
37+
import { Routes } from '~/types'
38+
39+
@Component({
40+
components: { SocialShare }
41+
})
42+
export default class TopImage extends Vue {
43+
get routes () {
44+
return Routes
45+
}
46+
}
47+
</script>

src/components/navbar/TopNavbar.vue

+16-21
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,16 @@
1111
<strong>{{ $t('topNavbar.home') }}</strong>
1212
</b-navbar-item>
1313

14-
<b-navbar-item
15-
:to="routes.LIGHT_BOX"
16-
tag="router-link"
17-
>
18-
{{ $t('topNavbar.lightbox') }}
19-
</b-navbar-item>
20-
21-
<b-navbar-item
22-
:to="routes.CROP"
23-
tag="router-link"
24-
>
25-
{{ $t('topNavbar.crop') }}
26-
</b-navbar-item>
27-
28-
<b-navbar-item
29-
:to="routes.IMAGES"
30-
tag="router-link"
31-
>
32-
{{ $t('topNavbar.images') }}
33-
</b-navbar-item>
14+
<TopImage />
3415
</template>
3516

3617
<template slot="end">
3718
<SearchBar :auth-user="authUser" class="has-margin-top-10" />
3819

3920
<LanguageSwitcher />
4021

22+
<TopShare />
23+
4124
<TopPushNotification v-if="authUser" :auth-user="authUser" />
4225

4326
<b-navbar-item v-if="authUser" tag="router-link" :to="dynamicProfileRoute">
@@ -46,6 +29,7 @@
4629
<span class="has-margin-left-5"><b>{{ authUser.name || authUser.email }}</b></span>
4730
</b-field>
4831
</b-navbar-item>
32+
4933
<ProfileNavigator v-if="authUser" :auth-user="authUser" :logout="logout" />
5034

5135
<b-navbar-item v-else tag="div">
@@ -82,9 +66,20 @@ import SearchBar from '~/components/navbar/SearchBar.vue'
8266
import { getUserRoute } from '~/service/global-service'
8367
import BackgroundSquareImage from '~/components/image/BackgroundSquareImage.vue'
8468
import TopPushNotification from '~/components/navbar/TopPushNotification.vue'
69+
import TopShare from '~/components/navbar/TopShare.vue'
70+
import TopImage from '~/components/navbar/TopImage.vue'
8571
8672
@Component({
87-
components: { TopPushNotification, BackgroundSquareImage, SearchBar, Logo, ProfileNavigator, LanguageSwitcher }
73+
components: {
74+
TopImage,
75+
TopShare,
76+
TopPushNotification,
77+
BackgroundSquareImage,
78+
SearchBar,
79+
Logo,
80+
ProfileNavigator,
81+
LanguageSwitcher
82+
}
8883
})
8984
export default class TopNavbar extends Vue {
9085
@StateNamespace.auth.Getter readonly authUser: AuthUser

src/components/navbar/TopPushNotification.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<b-navbar-dropdown :arrowless="true" :close-on-click="true" :boxed="true">
2+
<b-navbar-dropdown :arrowless="true" :close-on-click="true" :boxed="true" right>
33
<template slot="label">
44
<b-icon
55
v-if="hasNewNotification"

src/components/navbar/TopShare.vue

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<template>
2+
<b-navbar-dropdown :boxed="true" :close-on-click="true" :arrowless="true" hoverable right>
3+
<template slot="label">
4+
<b-icon
5+
icon="share-variant"
6+
type="is-primary"
7+
/>
8+
<small class="has-text-primary">Share</small>
9+
</template>
10+
11+
<b-navbar-item>
12+
<div class="block">
13+
<client-only>
14+
<SocialShare v-for="(socialMetaConfig, index) in socialMetaConfigs" :key="index" :page-meta="defaultMeta"
15+
:social-meta-config="socialMetaConfig"
16+
/>
17+
</client-only>
18+
</div>
19+
</b-navbar-item>
20+
</b-navbar-dropdown>
21+
</template>
22+
23+
<script lang="ts">
24+
import { Component, Vue } from 'nuxt-property-decorator'
25+
import SocialShare from '~/components/ui/social/SocialShare.vue'
26+
import { DefaultMeta, SocialMetaConfigs } from '~/types'
27+
28+
@Component({
29+
components: { SocialShare }
30+
})
31+
export default class TopShare extends Vue {
32+
get defaultMeta () {
33+
return DefaultMeta
34+
}
35+
36+
get socialMetaConfigs () {
37+
return SocialMetaConfigs
38+
}
39+
}
40+
</script>
+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<template>
2+
<a :href="shareLink" target="_blank" class="has-margin-right-20" @click="shared()">
3+
<b-icon :icon="socialMetaConfig.icon" :type="socialMetaConfig.type" />
4+
</a>
5+
</template>
6+
7+
<script lang="ts">
8+
import { Component, Prop, Vue } from 'nuxt-property-decorator'
9+
import { PageMeta, SocialMetaConfig, SocialMetaType } from '~/types'
10+
11+
@Component({
12+
components: {}
13+
})
14+
export default class SocialShare extends Vue {
15+
@Prop({ type: Object, required: true }) readonly socialMetaConfig: SocialMetaConfig
16+
@Prop({ type: Object, required: true }) readonly pageMeta: PageMeta
17+
18+
get rawLink () {
19+
const ua = navigator.userAgent.toLowerCase()
20+
21+
/**
22+
* On IOS, SMS sharing link need a special formatting
23+
* Source: https://weblog.west-wind.com/posts/2013/Oct/09/Prefilling-an-SMS-on-Mobile-Devices-with-the-sms-Uri-Scheme#Body-only
24+
*/
25+
if (this.socialMetaConfig.type === SocialMetaType.SMS && (ua?.includes('iphone') || ua?.includes('ipad'))) {
26+
return this.socialMetaConfig.shareLink.replace(':?', ':&')
27+
}
28+
29+
return this.socialMetaConfig.shareLink
30+
}
31+
32+
get encodedHashtags () {
33+
if (this.socialMetaConfig.type === SocialMetaType.FACEBOOK && this.pageMeta.tags.length) {
34+
return '%23' + this.pageMeta.tags.split(',')[0] + ' %23ahanda'
35+
}
36+
37+
return this.pageMeta.tags
38+
}
39+
40+
get shareLink () {
41+
let link = this.rawLink
42+
43+
/**
44+
* Twitter sharing shouldn't include empty parameter
45+
* Source: https://github.com/nicolasbeauvais/vue-social-sharing/issues/143
46+
*/
47+
if (this.socialMetaConfig.type === SocialMetaType.TWITTER) {
48+
if (!this.pageMeta.tags?.length) {
49+
link = link.replace('&hashtags=@h', '')
50+
}
51+
}
52+
53+
console.log('LINK', link)
54+
55+
return link
56+
.replace(/@u/g, encodeURIComponent(this.pageMeta.url))
57+
.replace(/@t/g, encodeURIComponent(this.pageMeta.title))
58+
.replace(/@d/g, encodeURIComponent(this.pageMeta.description))
59+
.replace(/@h/g, this.encodedHashtags)
60+
.replace(/@m/g, encodeURIComponent(this.pageMeta.image.src))
61+
}
62+
63+
shared () {
64+
console.log('Clicked on ' + this.socialMetaConfig.type)
65+
}
66+
}
67+
</script>

src/layouts/default.vue

+4
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,7 @@ export default class defaultLayout extends Vue {
4949
}
5050
5151
</script>
52+
53+
<style lang="scss">
54+
@import 'assets/main';
55+
</style>

src/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,9 @@
9090
"husky": "^4.2.5",
9191
"jest": "^26.1.0",
9292
"lint-staged": "^10.2.11",
93+
"node-sass": "^4.14.1",
9394
"prettier": "^2.0.5",
95+
"sass-loader": "^9.0.2",
9496
"stylelint": "^13.6.1",
9597
"ts-jest": "^26.1.1",
9698
"vue-jest": "^4.0.0-0"

src/tsconfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
"@nuxtjs/axios",
3333
"nuxt-i18n",
3434
"cookie-universal-nuxt",
35-
"firebase"
35+
"firebase",
36+
"types-module",
37+
"handlers-module"
3638
]
3739
},
3840
"exclude": [

0 commit comments

Comments
 (0)