Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Photo page overhaul #653

Merged
merged 9 commits into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ Or use [overmind](https://github.com/DarthSim/overmind): `overmind s -N -f Procf
-e SE_EVENT_BUS_SUBSCRIBE_PORT=4443 \
selenium/node-chrome:latest

## Deployment
## Versioning & Deployment

1. Draft a new release on the [releases page](https://github.com/photonia-io/photonia/releases)
1. Update the [changelog](CHANGELOG.md)
2. Draft a new release on the [releases page](https://github.com/photonia-io/photonia/releases)
- Create a tag with the prefix **release-** and the version, eg: **0.1.3** (resulting tag: **release-0.1.3**)
- Prefix the release title with the release version, eg: **0.1.3 - An awesome release**
2. Publish the release
3. Go to Jenkins and build the tag
3. Publish the release
4. Go to Jenkins and build the tag
6 changes: 6 additions & 0 deletions app/graphql/graphql_query_collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ class GraphqlQueryCollection
extralargeImageUrl: imageUrl(type: "extralarge")
takenAt
isTakenAtFromExif
exifExists
exifCameraFriendlyName
exifFNumber
exifExposureTime
exifFocalLength
exifIso
postedAt
impressionsCount
previousPhoto {
Expand Down
10 changes: 10 additions & 0 deletions app/graphql/types/photo_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ class PhotoType < Types::BaseObject

field :albums, [AlbumType], 'Albums the photo belongs to', null: true
field :description, String, 'Description', null: false
field :exif_camera_friendly_name, String, 'Camera friendly name', null: true
field :exif_f_number, Float, 'F number', null: true
field :exif_exposure_time, String, 'Exposure time', null: true
field :exif_iso, Integer, 'ISO', null: true
field :exif_exists, Boolean, 'Whether EXIF data exists', null: true
field :exif_focal_length, Float, 'Focal length', null: true
field :height, Integer, 'Height of the photo in pixels', null: true
field :id, String, 'ID of the photo', null: false
field :impressions_count, Integer, 'Number of impressions', null: true
Expand Down Expand Up @@ -89,5 +95,9 @@ def width
def height
@object.pixel_height
end

def exif_exists
@object.exif_exists?
end
end
end
7 changes: 7 additions & 0 deletions app/javascript/entrypoints/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ document.addEventListener("DOMContentLoaded", () => {
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ top: 0, behavior: "smooth" });
}, 50);
});
},
});

const tokenStore = useTokenStore(pinia);
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/photos/display-hero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const showLabels = computed(() => {
display: flex;
flex-direction: column;
border-radius: 5px;
overflow: scroll;
overflow: auto;
max-height: calc(100% - 15px);
}

Expand Down
28 changes: 15 additions & 13 deletions app/javascript/photos/photo-info.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<template>
<SidebarHeader icon="fas fa-info-circle" title="Info" />
<div class="block">
<span class="icon-text is-size-7">
<!-- display views -->
<PhotoInfobox>
<template #header>
<SidebarHeader icon="fas fa-info-circle" title="Info" />
</template>
<div class="icon-text">
<span class="icon"><i class="fas fa-eye"></i></span>
<span class="has-text-weight-semibold">Views:</span>
<span v-if="!loading" class="ml-1">{{ photo.impressionsCount }}</span>
</span>
<span class="icon-text is-size-7">
</div>
<div class="icon-text">
<span class="icon"><i class="fas fa-camera"></i></span>
<span class="has-text-weight-semibold">Date Taken:</span>
<span v-if="!loading" class="ml-1">{{
Expand All @@ -19,28 +20,29 @@
>
EXIF
</span>
</span>
<span class="icon-text is-size-7">
</div>
<div class="icon-text">
<span class="icon"><i class="fas fa-arrow-circle-up"></i></span>
<span class="has-text-weight-semibold">Date Posted:</span>
<span v-if="!loading" class="ml-1">{{
momentFormat(photo.postedAt)
}}</span>
</span>
<span
</div>
<div
v-if="!loading && photo.rekognitionLabelModelVersion !== ''"
class="icon-text is-size-7"
class="icon-text"
>
<span class="icon"><i class="fas fa-robot"></i></span>
<span class="has-text-weight-semibold"
>Rekognition Label Model Version:</span
>
<span class="ml-1">{{ photo.rekognitionLabelModelVersion }}</span>
</span>
</div>
</div>
</PhotoInfobox>
</template>

<script setup>
import PhotoInfobox from "./photo-infobox.vue";
import SidebarHeader from "./sidebar-header.vue";
import moment from "moment/min/moment-with-locales";

Expand Down
34 changes: 34 additions & 0 deletions app/javascript/photos/photo-infobox.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<div class="message is-smallish is-lightgray">
<div class="message-header">
<slot name="header"></slot>
</div>
<div class="message-body">
<slot></slot>
</div>
</div>
</template>

<style scoped>
.message {
background-color: hsl(0, 0%, 98%);
}
.message p {
display: block;
}
.message.is-smallish {
font-size: 0.9rem;
}
.message-body {
padding: 1em 1em;
}

.message.is-lightgray .message-header {
background-color: hsl(0, 0%, 95%);
color: #363636;
}

.message.is-lightgray .message-body {
color: #363636;
}
</style>
134 changes: 83 additions & 51 deletions app/javascript/photos/show.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,45 +59,89 @@
@delete-photo="deletePhoto"
/>

<PhotoInfo :photo="photo" :loading="loading" />

<div
class="message is-smallish is-lightgray"
v-if="photo.labels?.length > 0"
>
<div class="message-header">Labels</div>
<div class="message-body">
<div class="tags">
<LabelListItem
v-for="label in photo.labels"
@highlight-label="highlightLabel"
@un-highlight-label="unHighlightLabel"
:label="label"
:hoverable="false"
:key="label.id"
/>
</div>
<label class="checkbox">
<input type="checkbox" v-model="showLabelsOnHero" />
Display labels on the photo
</label>
<div class="columns equal-height-columns">
<div class="column is-half">
<PhotoInfo :photo="photo" :loading="loading" />
</div>
<div class="column is-half">
<PhotoInfobox>
<template #header>
<SidebarHeader icon="fas fa-camera" title="EXIF" />
</template>
<div class="icon-text">
<span class="icon"
><i class="fas fa-camera-retro"></i
></span>
<span v-if="!loading">
<span v-if="photo.exifExists">
{{ photo.exifCameraFriendlyName }}
</span>
<span v-else>
<em>No EXIF data available</em>
</span>
</span>
</div>
<div class="icon-text">
<span class="icon"><i class="fas fa-cog"></i></span>
<span v-if="!loading">
<span v-if="photo.exifExists">
f/{{ photo.exifFNumber }} &middot;
{{ photo.exifExposureTime }}s &middot;
{{ photo.exifFocalLength }}mm &middot; ISO
{{ photo.exifIso }}
</span>
<span v-else>
<em>No EXIF data available</em>
</span>
</span>
</div>
</PhotoInfobox>
</div>
</div>

<SidebarHeader icon="fas fa-tag" title="Tags" />
<div class="tags">
<Tag v-for="tag in photo.userTags" :key="tag.id" :tag="tag" />
</div>

<SidebarHeader icon="fas fa-robot" title="Machine Tags" />
<div class="tags">
<Tag
v-for="tag in photo.machineTags"
:key="tag.id"
:tag="tag"
type="machine"
/>
</div>
<PhotoInfobox v-if="photo.labels?.length > 0">
<template #header>Labels</template>
<div class="tags">
<LabelListItem
v-for="label in photo.labels"
@highlight-label="highlightLabel"
@un-highlight-label="unHighlightLabel"
:label="label"
:hoverable="false"
:key="label.id"
/>
</div>
<label class="checkbox">
<input type="checkbox" v-model="showLabelsOnHero" />
Display labels on the photo
</label>
</PhotoInfobox>

<PhotoInfobox>
<template #header
><SidebarHeader icon="fas fa-tag" title="Tags"
/></template>
<div class="tags" v-if="photo.userTags?.length > 0">
<Tag v-for="tag in photo.userTags" :key="tag.id" :tag="tag" />
</div>
<span v-else>
<em>There are no user tags for this photo.</em>
</span>
</PhotoInfobox>

<PhotoInfobox>
<template #header>
<SidebarHeader icon="fas fa-robot" title="Machine Tags" />
</template>
<div class="tags">
<Tag
v-for="tag in photo.machineTags"
:key="tag.id"
:tag="tag"
type="machine"
/>
</div>
</PhotoInfobox>
</div>
<!-- End left column -->
<div class="column is-one-quarter">
Expand Down Expand Up @@ -227,6 +271,7 @@ import PhotoTitleEditable from "./photo-title-editable.vue";
import PhotoDescriptionEditable from "./photo-description-editable.vue";
import PhotoAdministration from "./photo-administration.vue";
import PhotoInfo from "./photo-info.vue";
import PhotoInfobox from "./photo-infobox.vue";
import SmallNavigationButton from "@/photos/small-navigation-button.vue";
import DisplayHero from "./display-hero.vue";
import SidebarHeader from "./sidebar-header.vue";
Expand Down Expand Up @@ -407,24 +452,11 @@ const navigateToPreviousPhoto = () => {
</script>

<style scoped>
.message.is-smallish {
font-size: 0.84rem;
}
.message-body {
padding: 1em 1em;
}

.message-body .tags {
margin-bottom: 0.2em;
}

.message.is-lightgray .message-header {
background-color: #dedede;
color: #363636;
}

.message.is-lightgray .message-body {
background-color: #f0f0f4;
color: #363636;
.equal-height-columns .message {
height: 100%;
}
</style>
10 changes: 4 additions & 6 deletions app/javascript/photos/sidebar-header.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
<template>
<h3 class="mb-2">
<span class="icon-text">
<span class="icon"><i :class="icon"></i></span>
<span>{{ title }}</span>
</span>
</h3>
<span class="icon-text">
<span class="icon"><i :class="icon"></i></span>
<span>{{ title }}</span>
</span>
</template>

<script setup>
Expand Down
47 changes: 47 additions & 0 deletions app/models/concerns/exif_utilities.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module EXIFUtilities
extend ActiveSupport::Concern

def exif_ifd0
exif['ifd0']
end

def exif_ifd1
exif['ifd1']
end

def exif_exif
exif['exif']
end

def exif_camera_make
exif_ifd0['make']
end

def exif_camera_model
exif_ifd0['model']
end

def exif_camera_friendly_name
if exif_exists? && exif_camera_make && exif_camera_model
CameraUtilities.new(exif_camera_make, exif_camera_model).friendly_name
else
''
end
end

def exif_f_number
exif_exif['fnumber'].to_f if exif_exists? && exif_exif['fnumber']
end

def exif_exposure_time
exif_exif['exposure_time'] if exif_exists? && exif_exif['exposure_time']
end

def exif_focal_length
exif_exif['focal_length'].to_f if exif_exists? && exif_exif['focal_length']
end

def exif_iso
exif_exif['iso_speed_ratings'].to_i if exif_exists? && exif_exif['iso_speed_ratings']
end
end
1 change: 1 addition & 0 deletions app/models/photo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Photo < ApplicationRecord

include ImageUploader::Attachment(:image)
include SerialNumberSetter
include EXIFUtilities

include PgSearch::Model
pg_search_scope :search,
Expand Down
Loading