forked from trent_larson/crowd-funder-for-time-pwa
Compare commits
6 Commits
035f2a5b04
...
photo-reve
| Author | SHA1 | Date | |
|---|---|---|---|
| 9059f7a9a7 | |||
| e6cd86618e | |||
| c3fd27b140 | |||
| cf2e800dec | |||
| b60383cfe9 | |||
| c7d93db6f2 |
@@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Nothing
|
||||
|
||||
|
||||
## [0.3.4] - 2024.03.21
|
||||
## [0.3.5] - 2024.03.23
|
||||
### Added
|
||||
- Photo on gift records
|
||||
### Fixed
|
||||
|
||||
34
package-lock.json
generated
34
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "TimeSafari",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "TimeSafari",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.5",
|
||||
"dependencies": {
|
||||
"@dicebear/collection": "^5.3.5",
|
||||
"@dicebear/core": "^5.3.5",
|
||||
@@ -16240,9 +16240,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -17449,9 +17449,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ip": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
|
||||
"integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz",
|
||||
"integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
@@ -18941,9 +18941,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "4.15.4",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
|
||||
"integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
|
||||
"version": "4.15.5",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz",
|
||||
"integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==",
|
||||
"optional": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
@@ -27295,9 +27295,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
"version": "5.26.3",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.26.3.tgz",
|
||||
"integrity": "sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==",
|
||||
"version": "5.28.3",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
|
||||
"integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@fastify/busboy": "^2.0.0"
|
||||
@@ -28018,9 +28018,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-dev-middleware": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
|
||||
"integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
|
||||
"version": "5.3.4",
|
||||
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
|
||||
"integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"colorette": "^2.0.10",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "TimeSafari",
|
||||
"version": "0.3.4",
|
||||
"version": "0.3.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
}"
|
||||
class="text-blue-500"
|
||||
>
|
||||
More Options
|
||||
Photo, ...
|
||||
</router-link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -43,22 +43,45 @@
|
||||
<img :src="URL.createObjectURL(blob)" class="mt-2 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-else ref="cameraContainer">
|
||||
<!--
|
||||
Camera "resolution" doesn't change how it shows on screen but rather stretches the result, eg the following which just stretches it vertically:
|
||||
:resolution="{ width: 375, height: 812 }"
|
||||
-->
|
||||
<camera facingMode="environment" autoplay ref="camera">
|
||||
<camera
|
||||
facingMode="environment"
|
||||
autoplay
|
||||
ref="camera"
|
||||
@started="cameraStarted()"
|
||||
>
|
||||
<div
|
||||
class="absolute portrait:bottom-0 portrait:left-0 portrait:right-0 landscape:right-0 landscape:top-0 landscape:bottom-0 flex landscape:flex-row justify-center items-center portrait:pb-2 landscape:pr-4"
|
||||
class="absolute portrait:bottom-0 portrait:left-0 portrait:right-0 portrait:pb-2 landscape:right-0 landscape:top-0 landscape:bottom-0 landscape:pr-4 flex landscape:flex-row justify-center items-center"
|
||||
>
|
||||
<button
|
||||
@click="takeImage"
|
||||
@click="takeImage()"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold p-3 rounded-full text-2xl leading-none"
|
||||
>
|
||||
<fa icon="camera" class="w-[1em]"></fa>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="absolute portrait:bottom-2 portrait:right-16 landscape:right-0 landscape:bottom-16 landscape:pr-4 flex justify-center items-center"
|
||||
>
|
||||
<button
|
||||
@click="swapMirrorClass()"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold p-3 rounded-full text-2xl leading-none"
|
||||
>
|
||||
<fa icon="left-right" class="w-[1em]"></fa>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="numDevices > -1" class="absolute bottom-2 right-4">
|
||||
<button
|
||||
@click="switchCamera()"
|
||||
class="bg-blue-500 hover:bg-blue-700 text-white font-bold p-3 rounded-full text-2xl leading-none"
|
||||
>
|
||||
<fa icon="rotate" class="w-[1em]"></fa>
|
||||
</button>
|
||||
</div>
|
||||
</camera>
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,12 +103,12 @@ import { accessToken } from "@/libs/crypto";
|
||||
export default class GiftedPhotoDialog extends Vue {
|
||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||
|
||||
activeDeviceNumber = 0;
|
||||
activeDid = "";
|
||||
blob: Blob | null = null;
|
||||
mirror = false;
|
||||
numDevices = 0;
|
||||
setImage: (arg: string) => void = () => {};
|
||||
imageHeight?: number = window.innerHeight / 2;
|
||||
imageWidth?: number = window.innerWidth / 2;
|
||||
imageWarning = ".";
|
||||
uploading = false;
|
||||
visible = false;
|
||||
|
||||
@@ -129,6 +152,21 @@ export default class GiftedPhotoDialog extends Vue {
|
||||
this.blob = null;
|
||||
}
|
||||
|
||||
async cameraStarted() {
|
||||
const cameraComponent = this.$refs.camera as InstanceType<typeof Camera>;
|
||||
if (cameraComponent) {
|
||||
this.numDevices = (await cameraComponent.devices(["videoinput"])).length;
|
||||
this.mirror = cameraComponent.facingMode === "user";
|
||||
}
|
||||
}
|
||||
|
||||
async switchCamera() {
|
||||
const cameraComponent = this.$refs.camera as InstanceType<typeof Camera>;
|
||||
this.activeDeviceNumber = (this.activeDeviceNumber + 1) % this.numDevices;
|
||||
const devices = await cameraComponent?.devices(["videoinput"]);
|
||||
cameraComponent?.changeCamera(devices[this.activeDeviceNumber].deviceId);
|
||||
}
|
||||
|
||||
async takeImage(/* payload: MouseEvent */) {
|
||||
const cameraComponent = this.$refs.camera as InstanceType<typeof Camera>;
|
||||
|
||||
@@ -200,7 +238,6 @@ export default class GiftedPhotoDialog extends Vue {
|
||||
<canvas id="canvas" width="320" height="240"></canvas>
|
||||
|
||||
async cameraClicked() {
|
||||
console.log("camera_button clicked");
|
||||
const video = document.querySelector("#video");
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
@@ -211,7 +248,6 @@ export default class GiftedPhotoDialog extends Vue {
|
||||
}
|
||||
}
|
||||
photoSnapped() {
|
||||
console.log("snap_photo clicked");
|
||||
const video = document.querySelector("#video");
|
||||
const canvas = document.querySelector("#canvas");
|
||||
if (
|
||||
@@ -232,7 +268,6 @@ export default class GiftedPhotoDialog extends Vue {
|
||||
|
||||
// data url of the image
|
||||
const image_data_url = canvas?.toDataURL("image/jpeg");
|
||||
console.log(image_data_url);
|
||||
}
|
||||
}
|
||||
****/
|
||||
@@ -287,6 +322,17 @@ export default class GiftedPhotoDialog extends Vue {
|
||||
this.blob = null;
|
||||
}
|
||||
}
|
||||
|
||||
swapMirrorClass() {
|
||||
this.mirror = !this.mirror;
|
||||
if (this.mirror) {
|
||||
(this.$refs.cameraContainer as HTMLElement).classList.add("mirror-video");
|
||||
} else {
|
||||
(this.$refs.cameraContainer as HTMLElement).classList.remove(
|
||||
"mirror-video",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -311,4 +357,12 @@ export default class GiftedPhotoDialog extends Vue {
|
||||
width: 100%;
|
||||
max-width: 700px;
|
||||
}
|
||||
|
||||
.mirror-video {
|
||||
transform: scaleX(-1);
|
||||
-webkit-transform: scaleX(-1); /* For Safari */
|
||||
-moz-transform: scaleX(-1); /* For Firefox */
|
||||
-ms-transform: scaleX(-1); /* For IE */
|
||||
-o-transform: scaleX(-1); /* For Opera */
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
faHand,
|
||||
faHandHoldingHeart,
|
||||
faHouseChimney,
|
||||
faLeftRight,
|
||||
faLocationDot,
|
||||
faLongArrowAltLeft,
|
||||
faLongArrowAltRight,
|
||||
@@ -105,6 +106,7 @@ library.add(
|
||||
faHand,
|
||||
faHandHoldingHeart,
|
||||
faHouseChimney,
|
||||
faLeftRight,
|
||||
faLocationDot,
|
||||
faLongArrowAltLeft,
|
||||
faLongArrowAltRight,
|
||||
|
||||
@@ -198,9 +198,7 @@
|
||||
<ul>
|
||||
<li class="list-disc list-outside ml-4">
|
||||
Chrome:
|
||||
<a href="chrome://settings/content/all" class="text-blue-500"
|
||||
>clear here</a
|
||||
>
|
||||
Clear at chrome://settings/content/all and
|
||||
also clear under dev tools Application
|
||||
</li>
|
||||
<li class="list-disc list-outside ml-4">
|
||||
|
||||
@@ -265,6 +265,8 @@ export default class NewEditProjectView extends Vue {
|
||||
vcClaim.agent = {
|
||||
identifier: this.agentDid,
|
||||
};
|
||||
} else {
|
||||
delete vcClaim.agent;
|
||||
}
|
||||
if (this.includeLocation) {
|
||||
vcClaim.location = {
|
||||
@@ -274,6 +276,8 @@ export default class NewEditProjectView extends Vue {
|
||||
longitude: this.longitude,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
delete vcClaim.location;
|
||||
}
|
||||
// Make a payload for the claim
|
||||
const vcPayload = {
|
||||
|
||||
Reference in New Issue
Block a user