WIP working on sorting recently published by capture date when published in batches
This commit is contained in:
		| @@ -10,6 +10,10 @@ import sharp from "sharp"; | ||||
| import { Palette } from "node-vibrant/lib/color"; | ||||
| import { performance } from "perf_hooks"; | ||||
|  | ||||
| import util from 'node:util'; | ||||
| import { exec as _exec } from "child_process"; | ||||
| const exec = util.promisify(_exec) | ||||
|  | ||||
| // const path = require("path"); | ||||
| // const Vibrant = require("node-vibrant"); | ||||
| // const chroma = require("chroma-js"); | ||||
| @@ -114,7 +118,8 @@ function transformMetaToNodeData( | ||||
|   metaData: Record<string, unknown>, | ||||
|   vibrantData: Palette, | ||||
|   imagePath: string, | ||||
|   { r, g, b }: { r: number; b: number; g: number } | ||||
|   { r, g, b }: { r: number; b: number; g: number }, | ||||
|   datePublished: string, | ||||
| ) { | ||||
|   const vibrant = vibrantData ? processColors(vibrantData, imagePath) : null; | ||||
|   const vibrantHue = vibrantData.Vibrant!.getHsl()[0] * 360; | ||||
| @@ -131,6 +136,7 @@ function transformMetaToNodeData( | ||||
|   } | ||||
|   return { | ||||
|     dateTaken: metaData.DateTimeOriginal, | ||||
|     datePublished, | ||||
|     meta: { | ||||
|       Make: metaData.Make, | ||||
|       Model: metaData.Model, | ||||
| @@ -174,6 +180,11 @@ export const onCreateNode: GatsbyNode["onCreateNode"] = async function ({ | ||||
|   const { createNodeField } = actions; | ||||
|  | ||||
|   if (node.internal.type === "File" && node.sourceInstanceName === "gallery") { | ||||
|     const { stdout: datePublished, stderr } = await exec(`git log --diff-filter=A --follow --format=%aI -1 -- ${node.absolutePath}`) | ||||
|     if (stderr.length) { | ||||
|       console.error('something went wrong checking publish date: ', stderr); | ||||
|     } | ||||
|  | ||||
|     const metaData = await exifr.parse(node.absolutePath as string, { | ||||
|       iptc: true, | ||||
|       xmp: true, | ||||
| @@ -201,7 +212,8 @@ export const onCreateNode: GatsbyNode["onCreateNode"] = async function ({ | ||||
|         metaData, | ||||
|         vibrantData, | ||||
|         node.absolutePath as string, | ||||
|         dominant | ||||
|         dominant, | ||||
|         datePublished | ||||
|       ), | ||||
|     }); | ||||
|   } | ||||
|   | ||||
							
								
								
									
										193
									
								
								scratchpad.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								scratchpad.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,193 @@ | ||||
| a = { | ||||
|   ApplicationRecordVersion: '\x00\x04', | ||||
|   DateCreated: '2015-10-18T17:59:38', | ||||
|   TimeCreated: '175938', | ||||
|   DigitalCreationDate: '20151018', | ||||
|   DigitalCreationTime: '175938', | ||||
|   format: 'image/jpeg', | ||||
|   CreatorTool: 'Adobe Lightroom 5.4 (Macintosh)', | ||||
|   ModifyDate: '2022-07-09T21:16:39.000Z', | ||||
|   CreateDate: '2015-10-19T00:59:38.000Z', | ||||
|   MetadataDate: '2022-07-09T14:16:39-07:00', | ||||
|   Rating: 5, | ||||
|   LensInfo: [ 50, 50, 1.8, 1.8 ], | ||||
|   Lens: 'DT 50mm F1.8 SAM', | ||||
|   DocumentID: 'xmp.did:27795bf1-8bb2-49a0-807a-cf6150bd505b', | ||||
|   OriginalDocumentID: 'CE2B8F240393ADFDF9F092CF395C6632', | ||||
|   InstanceID: 'xmp.iid:27795bf1-8bb2-49a0-807a-cf6150bd505b', | ||||
|   History: [ | ||||
|     { action: 'derived', parameters: 'saved to new location' }, | ||||
|     { | ||||
|       action: 'saved', | ||||
|       instanceID: 'xmp.iid:27795bf1-8bb2-49a0-807a-cf6150bd505b', | ||||
|       when: '2022-07-09T14:16:39-07:00', | ||||
|       softwareAgent: 'Adobe Lightroom 5.4 (Macintosh)', | ||||
|       changed: '/' | ||||
|     } | ||||
|   ], | ||||
|   DerivedFrom: { | ||||
|     documentID: 'CE2B8F240393ADFDF9F092CF395C6632', | ||||
|     originalDocumentID: 'CE2B8F240393ADFDF9F092CF395C6632' | ||||
|   }, | ||||
|   good: true, | ||||
|   Version: 14.4, | ||||
|   ProcessVersion: 6.7, | ||||
|   WhiteBalance: 'Manual', | ||||
|   IncrementalTemperature: -11, | ||||
|   IncrementalTint: 23, | ||||
|   Exposure2012: 0, | ||||
|   Contrast2012: 6, | ||||
|   Highlights2012: 0, | ||||
|   Shadows2012: 0, | ||||
|   Whites2012: 35, | ||||
|   Blacks2012: -22, | ||||
|   Texture: 0, | ||||
|   Clarity2012: 0, | ||||
|   Dehaze: 0, | ||||
|   Vibrance: 0, | ||||
|   Saturation: 'Normal', | ||||
|   ParametricShadows: 0, | ||||
|   ParametricDarks: 0, | ||||
|   ParametricLights: 0, | ||||
|   ParametricHighlights: 0, | ||||
|   ParametricShadowSplit: 25, | ||||
|   ParametricMidtoneSplit: 50, | ||||
|   ParametricHighlightSplit: 75, | ||||
|   Sharpness: 'Normal', | ||||
|   LuminanceSmoothing: 0, | ||||
|   ColorNoiseReduction: 0, | ||||
|   HueAdjustmentRed: 0, | ||||
|   HueAdjustmentOrange: 0, | ||||
|   HueAdjustmentYellow: 0, | ||||
|   HueAdjustmentGreen: 0, | ||||
|   HueAdjustmentAqua: 0, | ||||
|   HueAdjustmentBlue: 0, | ||||
|   HueAdjustmentPurple: 0, | ||||
|   HueAdjustmentMagenta: 0, | ||||
|   SaturationAdjustmentRed: 0, | ||||
|   SaturationAdjustmentOrange: 0, | ||||
|   SaturationAdjustmentYellow: 0, | ||||
|   SaturationAdjustmentGreen: 0, | ||||
|   SaturationAdjustmentAqua: 0, | ||||
|   SaturationAdjustmentBlue: 0, | ||||
|   SaturationAdjustmentPurple: 0, | ||||
|   SaturationAdjustmentMagenta: 0, | ||||
|   LuminanceAdjustmentRed: 0, | ||||
|   LuminanceAdjustmentOrange: 0, | ||||
|   LuminanceAdjustmentYellow: 0, | ||||
|   LuminanceAdjustmentGreen: 0, | ||||
|   LuminanceAdjustmentAqua: 0, | ||||
|   LuminanceAdjustmentBlue: 0, | ||||
|   LuminanceAdjustmentPurple: 0, | ||||
|   LuminanceAdjustmentMagenta: 0, | ||||
|   SplitToningShadowHue: 0, | ||||
|   SplitToningShadowSaturation: 0, | ||||
|   SplitToningHighlightHue: 0, | ||||
|   SplitToningHighlightSaturation: 0, | ||||
|   SplitToningBalance: 0, | ||||
|   ColorGradeMidtoneHue: 0, | ||||
|   ColorGradeMidtoneSat: 0, | ||||
|   ColorGradeShadowLum: 0, | ||||
|   ColorGradeMidtoneLum: 0, | ||||
|   ColorGradeHighlightLum: 0, | ||||
|   ColorGradeBlending: 50, | ||||
|   ColorGradeGlobalHue: 0, | ||||
|   ColorGradeGlobalSat: 0, | ||||
|   ColorGradeGlobalLum: 0, | ||||
|   AutoLateralCA: 0, | ||||
|   LensProfileEnable: 0, | ||||
|   LensManualDistortionAmount: 0, | ||||
|   VignetteAmount: 0, | ||||
|   DefringePurpleAmount: 0, | ||||
|   DefringePurpleHueLo: 30, | ||||
|   DefringePurpleHueHi: 70, | ||||
|   DefringeGreenAmount: 0, | ||||
|   DefringeGreenHueLo: 40, | ||||
|   DefringeGreenHueHi: 60, | ||||
|   PerspectiveUpright: 0, | ||||
|   PerspectiveVertical: 0, | ||||
|   PerspectiveHorizontal: 0, | ||||
|   PerspectiveRotate: 0, | ||||
|   PerspectiveAspect: 0, | ||||
|   PerspectiveScale: 100, | ||||
|   PerspectiveX: 0, | ||||
|   PerspectiveY: 0, | ||||
|   GrainAmount: 0, | ||||
|   PostCropVignetteAmount: 0, | ||||
|   ShadowTint: 0, | ||||
|   RedHue: 0, | ||||
|   RedSaturation: 0, | ||||
|   GreenHue: 0, | ||||
|   GreenSaturation: 0, | ||||
|   BlueHue: 0, | ||||
|   BlueSaturation: 0, | ||||
|   ConvertToGrayscale: false, | ||||
|   OverrideLookVignette: false, | ||||
|   ToneCurveName2012: 'Linear', | ||||
|   CameraProfile: 'Embedded', | ||||
|   CameraProfileDigest: '54650A341B5B5CCAE8442D0B43A92BCE', | ||||
|   HasSettings: true, | ||||
|   CropTop: 0, | ||||
|   CropLeft: 0, | ||||
|   CropBottom: 1, | ||||
|   CropRight: 1, | ||||
|   CropAngle: 0, | ||||
|   CropConstrainToWarp: 0, | ||||
|   HasCrop: false, | ||||
|   AlreadyApplied: true, | ||||
|   ToneCurvePV2012: [ '0, 0', '255, 255' ], | ||||
|   ToneCurvePV2012Red: [ '0, 0', '255, 255' ], | ||||
|   ToneCurvePV2012Green: [ '0, 0', '255, 255' ], | ||||
|   ToneCurvePV2012Blue: [ '0, 0', '255, 255' ], | ||||
|   Make: 'SONY', | ||||
|   Model: 'SLT-A55V', | ||||
|   XResolution: 240, | ||||
|   YResolution: 240, | ||||
|   ResolutionUnit: 'inches', | ||||
|   Software: 'Adobe Lightroom 5.4 (Macintosh)', | ||||
|   ExposureTime: 0.01, | ||||
|   FNumber: 1.8, | ||||
|   ExposureProgram: 'Manual', | ||||
|   ISO: 200, | ||||
|   SensitivityType: 2, | ||||
|   RecommendedExposureIndex: 200, | ||||
|   ExifVersion: '2.3.1', | ||||
|   DateTimeOriginal: '2015-10-19T00:59:38.000Z', | ||||
|   OffsetTime: '-07:00', | ||||
|   ShutterSpeedValue: 6.643856, | ||||
|   ApertureValue: 1.695994, | ||||
|   BrightnessValue: 3, | ||||
|   ExposureCompensation: 0, | ||||
|   MaxApertureValue: 1.7, | ||||
|   MeteringMode: 'Pattern', | ||||
|   LightSource: 'Cloudy weather', | ||||
|   Flash: 'Flash did not fire, compulsory flash mode', | ||||
|   FocalLength: 50, | ||||
|   ColorSpace: 1, | ||||
|   FileSource: 'Digital Camera', | ||||
|   SceneType: 'Directly photographed', | ||||
|   CustomRendered: 'Normal', | ||||
|   ExposureMode: 'Manual', | ||||
|   FocalLengthIn35mmFormat: 75, | ||||
|   SceneCaptureType: 'Standard', | ||||
|   Contrast: 'Normal', | ||||
|   LensModel: 'DT 50mm F1.8 SAM', | ||||
|   GPSVersionID: '2.2.0.0', | ||||
|   GPSLatitudeRef: 'N', | ||||
|   GPSLatitude: [ 33, 25.7121, 0 ], | ||||
|   GPSLongitudeRef: 'W', | ||||
|   GPSLongitude: [ 111, 55.57122, 0 ], | ||||
|   GPSAltitude: 354.7, | ||||
|   GPSTimeStamp: '19:2:7', | ||||
|   GPSStatus: 'V', | ||||
|   GPSMeasureMode: '3', | ||||
|   GPSSpeedRef: 'K', | ||||
|   GPSSpeed: 33.8, | ||||
|   GPSTrackRef: 'T', | ||||
|   GPSTrack: 0.36, | ||||
|   GPSMapDatum: 'WGS-84', | ||||
|   GPSDateStamp: '2015:10:09', | ||||
|   GPSDifferential: 0, | ||||
|   latitude: 33.428535, | ||||
|   longitude: -111.926187 | ||||
| } | ||||
| @@ -30,7 +30,7 @@ interface MasonryGalleryProps { | ||||
| } | ||||
|  | ||||
| const MasonryGallery = ({ | ||||
|   images, | ||||
|   images: _images, | ||||
|   aspectsByBreakpoint: aspectTargetsByBreakpoint, | ||||
|   debugHue, | ||||
|   debugRating, | ||||
| @@ -59,8 +59,8 @@ const MasonryGallery = ({ | ||||
|   }px)`; | ||||
|  | ||||
|   const aspectRatios = React.useMemo( | ||||
|     () => R.map(getAspectRatio, images).filter(Boolean), | ||||
|     [images] | ||||
|     () => R.map(getAspectRatio, _images).filter(Boolean), | ||||
|     [_images] | ||||
|   ) as number[]; | ||||
|  | ||||
|   const targetAspect = aspectTargetsByBreakpoint[breakpoint]; | ||||
| @@ -87,10 +87,7 @@ const MasonryGallery = ({ | ||||
|             } | ||||
|             // no-op instead of starting a new row | ||||
|             if (singleRow) { | ||||
|               return [ | ||||
|                 ...acc, | ||||
|                 currentRow, | ||||
|               ] | ||||
|               return [currentRow]; | ||||
|             } | ||||
|             // start a new row | ||||
|             return [ | ||||
| @@ -107,14 +104,16 @@ const MasonryGallery = ({ | ||||
|         ), | ||||
|         R.indexBy(R.prop("startIndex")) | ||||
|       )(aspectRatios), | ||||
|     [aspectRatios, targetAspect] | ||||
|     [aspectRatios, targetAspect, singleRow] | ||||
|   ); | ||||
|  | ||||
|   const sortedImageList = React.useMemo( | ||||
|     () => images.map((image) => image.base), | ||||
|     [images] | ||||
|     () => _images.map((image) => image.base), | ||||
|     [_images] | ||||
|   ); | ||||
|  | ||||
|   const images = singleRow ? _images.slice(0, rows[0].images) : _images; | ||||
|   | ||||
|   let cursor = 0; | ||||
|   return ( | ||||
|     <div | ||||
|   | ||||
| @@ -49,7 +49,7 @@ export function Select<T extends object>(props: AriaSelectProps<T>) { | ||||
|       <button | ||||
|         {...mergeProps(buttonProps, focusProps)} | ||||
|         className={`py-[5px] px-3 w-[150px] flex flex-row items-center justify-between overflow-hidden cursor-default rounded border hover:bg-transparentblack ${ | ||||
|           isFocusVisible ? "border-green-500" : "border-black" | ||||
|           isFocusVisible ? "border-green-700" : "border-black" | ||||
|         } ${state.isOpen ? "bg-gray-100" : "bg-white"}`} | ||||
|         ref={ref} | ||||
|       > | ||||
|   | ||||
							
								
								
									
										8
									
								
								src/gatsby-types.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								src/gatsby-types.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -571,6 +571,7 @@ type FileFieldsFilterInput = { | ||||
| }; | ||||
|  | ||||
| type FileFieldsImageMeta = { | ||||
|   readonly datePublished: Maybe<Scalars['String']>; | ||||
|   readonly dateTaken: Maybe<Scalars['Date']>; | ||||
|   readonly dominantHue: Maybe<ReadonlyArray<Maybe<Scalars['Float']>>>; | ||||
|   readonly meta: Maybe<FileFieldsImageMetaMeta>; | ||||
| @@ -587,6 +588,7 @@ type FileFieldsImageMeta_dateTakenArgs = { | ||||
| }; | ||||
|  | ||||
| type FileFieldsImageMetaFieldSelector = { | ||||
|   readonly datePublished: InputMaybe<FieldSelectorEnum>; | ||||
|   readonly dateTaken: InputMaybe<FieldSelectorEnum>; | ||||
|   readonly dominantHue: InputMaybe<FieldSelectorEnum>; | ||||
|   readonly meta: InputMaybe<FileFieldsImageMetaMetaFieldSelector>; | ||||
| @@ -595,6 +597,7 @@ type FileFieldsImageMetaFieldSelector = { | ||||
| }; | ||||
|  | ||||
| type FileFieldsImageMetaFilterInput = { | ||||
|   readonly datePublished: InputMaybe<StringQueryOperatorInput>; | ||||
|   readonly dateTaken: InputMaybe<DateQueryOperatorInput>; | ||||
|   readonly dominantHue: InputMaybe<FloatQueryOperatorInput>; | ||||
|   readonly meta: InputMaybe<FileFieldsImageMetaMetaFilterInput>; | ||||
| @@ -715,6 +718,7 @@ type FileFieldsImageMetaMetaSortInput = { | ||||
| }; | ||||
|  | ||||
| type FileFieldsImageMetaSortInput = { | ||||
|   readonly datePublished: InputMaybe<SortOrderEnum>; | ||||
|   readonly dateTaken: InputMaybe<SortOrderEnum>; | ||||
|   readonly dominantHue: InputMaybe<SortOrderEnum>; | ||||
|   readonly meta: InputMaybe<FileFieldsImageMetaMetaSortInput>; | ||||
| @@ -2559,12 +2563,12 @@ type GalleryImageQueryVariables = Exact<{ | ||||
|  | ||||
| type GalleryImageQuery = { readonly file: { readonly base: string, readonly publicURL: string | null, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly dateTaken: string | null, readonly meta: { readonly Make: string | null, readonly Model: string | null, readonly ExposureTime: number | null, readonly FNumber: number | null, readonly ISO: number | null, readonly DateTimeOriginal: string | null, readonly CreateDate: string | null, readonly ShutterSpeedValue: number | null, readonly ApertureValue: number | null, readonly FocalLength: number | null, readonly LensModel: string | null, readonly ObjectName: string | null, readonly Caption: string | null, readonly Location: string | null, readonly City: string | null, readonly State: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null } | null }; | ||||
|  | ||||
| type GalleryImageFileFragment = { readonly nodes: ReadonlyArray<{ readonly relativePath: string, readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null, readonly CreateDate: string | null, readonly ModifyDate: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> }; | ||||
| type GalleryImageFileFragment = { readonly nodes: ReadonlyArray<{ readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly datePublished: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null, readonly CreateDate: string | null, readonly ModifyDate: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> }; | ||||
|  | ||||
| type GalleryPageQueryQueryVariables = Exact<{ [key: string]: never; }>; | ||||
|  | ||||
|  | ||||
| type GalleryPageQueryQuery = { readonly recents: { readonly nodes: ReadonlyArray<{ readonly relativePath: string, readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null, readonly CreateDate: string | null, readonly ModifyDate: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> }, readonly all: { readonly nodes: ReadonlyArray<{ readonly relativePath: string, readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null, readonly CreateDate: string | null, readonly ModifyDate: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> } }; | ||||
| type GalleryPageQueryQuery = { readonly recents: { readonly nodes: ReadonlyArray<{ readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly datePublished: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null, readonly CreateDate: string | null, readonly ModifyDate: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> }, readonly all: { readonly nodes: ReadonlyArray<{ readonly base: string, readonly childImageSharp: { readonly gatsbyImageData: import('gatsby-plugin-image').IGatsbyImageData, readonly fluid: { readonly aspectRatio: number } | null } | null, readonly fields: { readonly imageMeta: { readonly vibrantHue: number | null, readonly dominantHue: ReadonlyArray<number | null> | null, readonly dateTaken: string | null, readonly datePublished: string | null, readonly meta: { readonly Keywords: ReadonlyArray<string | null> | null, readonly Rating: number | null, readonly ObjectName: string | null, readonly CreateDate: string | null, readonly ModifyDate: string | null } | null, readonly vibrant: { readonly DarkMuted: ReadonlyArray<number | null> | null, readonly DarkVibrant: ReadonlyArray<number | null> | null, readonly LightMuted: ReadonlyArray<number | null> | null, readonly LightVibrant: ReadonlyArray<number | null> | null, readonly Vibrant: ReadonlyArray<number | null> | null, readonly Muted: ReadonlyArray<number | null> | null } | null } | null } | null }> } }; | ||||
|  | ||||
| type GatsbyImageSharpFixedFragment = { readonly base64: string | null, readonly width: number, readonly height: number, readonly src: string, readonly srcSet: string }; | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import { Helmet } from "react-helmet"; | ||||
| import MasonryGallery from "../components/MasonryGallery"; | ||||
| import KeywordsPicker from "../components/KeywordsPicker"; | ||||
| import { | ||||
|   compareDates, | ||||
|   getGalleryPageUrl, | ||||
|   getHelmetSafeBodyStyle, | ||||
|   getVibrantStyle, | ||||
| @@ -19,14 +20,25 @@ import ColorPalette from "@spectrum-icons/workflow/ColorPalette"; | ||||
| const SORT_KEYS = { | ||||
|   hue: ["fields", "imageMeta", "vibrantHue"], | ||||
|   rating: ["fields", "imageMeta", "meta", "Rating"], | ||||
|   hue_debug: ["fields", "imageMeta", "dominantHue", 0], | ||||
|   // hue_debug: ["fields", "imageMeta", "dominantHue", 0], | ||||
|   hue_debug: ["fields", "imageMeta", "dominantHue", "0"], | ||||
|   date: ["fields", "imageMeta", "dateTaken"], | ||||
|   modified: ["fields", "imageMeta", "meta", "ModifyDate"] | ||||
|   modified: ["fields", "imageMeta", "datePublished"], | ||||
| } as const; | ||||
|  | ||||
| export type GalleryImage = | ||||
|   Queries.GalleryPageQueryQuery["all"]["nodes"][number]; | ||||
|  | ||||
| function smartCompareDates(key: keyof typeof SORT_KEYS, left: GalleryImage, right: GalleryImage) { | ||||
|   let diff = compareDates(SORT_KEYS[key], left, right); | ||||
|   console.log("🚀 ~ file: photogallery.tsx:34 ~ smartCompareDates ~ diff:", diff) | ||||
|   if (diff !== 0) { | ||||
|     return diff; | ||||
|   } | ||||
|   console.log('falling back to date') | ||||
|   return compareDates(SORT_KEYS.date, left, right); | ||||
| } | ||||
|  | ||||
| const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|   const hash = | ||||
|     typeof window !== "undefined" ? window.location.hash.replace("#", "") : ""; | ||||
| @@ -130,15 +142,7 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|   const images: GalleryImage[] = React.useMemo(() => { | ||||
|     const sort = | ||||
|       sortKey === "date" || sortKey === "modified" | ||||
|         ? R.sort((node1: typeof data["all"]["nodes"][number], node2) => { | ||||
|             const date1 = new Date( | ||||
|               R.pathOr("", SORT_KEYS[sortKey], node1) | ||||
|             ); | ||||
|             const date2 = new Date( | ||||
|               R.pathOr("", SORT_KEYS[sortKey], node2) | ||||
|             ); | ||||
|             return -1 * (date1.getTime() - date2.getTime()); | ||||
|           }) | ||||
|         ? R.sort((node1: typeof data["all"]["nodes"][number], node2) => smartCompareDates(sortKey, node1, node2)) | ||||
|         : R.sort( | ||||
|             // @ts-ignore | ||||
|             R.descend(R.path<GalleryImage>(SORT_KEYS[sortKey])) | ||||
| @@ -166,6 +170,10 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|     } | ||||
|   }, [data, sortKey, filterKeyword]); | ||||
|  | ||||
|   const recents = React.useMemo(() => { | ||||
|     return R.sort((left, right) => smartCompareDates('modified', left, right), data.recents.nodes) | ||||
|   }, [data, 'hi']) | ||||
|  | ||||
|   return ( | ||||
|     <> | ||||
|       {/* @ts-ignore */} | ||||
| @@ -198,7 +206,9 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|           /> | ||||
|         </div> | ||||
|         <div className="px-4 md:px-8"> | ||||
|           <h3 id="recently" className="mx-2 font-bold">Recently updated</h3> | ||||
|           <h3 id="recently" className="mx-2 font-bold"> | ||||
|             Recently published | ||||
|           </h3> | ||||
|         </div> | ||||
|         <MasonryGallery | ||||
|           aspectsByBreakpoint={{ | ||||
| @@ -210,11 +220,13 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|             "2xl": 6.1, | ||||
|             "3xl": 8, | ||||
|           }} | ||||
|           images={data.recents.nodes} | ||||
|           images={recents} | ||||
|           singleRow | ||||
|         /> | ||||
|         <div className="px-4 md:px-8 mt-4 pt-2 border-t"> | ||||
|           <h3 id="all" className="mx-2 font-bold">All images</h3> | ||||
|           <h3 id="all" className="mx-2 font-bold"> | ||||
|             All images | ||||
|           </h3> | ||||
|         </div> | ||||
|         <div className="flex flex-col lg:flex-row lg:items-end justify-between px-4 md:px-8 sm:mx-auto"> | ||||
|           <KeywordsPicker | ||||
| @@ -258,14 +270,14 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|               selectedKey={sortKey} | ||||
|             > | ||||
|               <Item key="rating">Curated</Item> | ||||
|               <Item key="modified">Date Updated</Item> | ||||
|               <Item key="modified">Date published</Item> | ||||
|               <Item key="date">Date taken</Item> | ||||
|               <Item key="hue">Hue</Item> | ||||
|             </Select> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|       <MasonryGallery | ||||
|       {/* <MasonryGallery | ||||
|         aspectsByBreakpoint={{ | ||||
|           xs: 2, | ||||
|           sm: 2, | ||||
| @@ -283,7 +295,7 @@ const GalleryPage = ({ data }: PageProps<Queries.GalleryPageQueryQuery>) => { | ||||
|           filterKeyword, | ||||
|         }} | ||||
|         showPalette={showPalette} | ||||
|       /> | ||||
|       /> */} | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| @@ -292,7 +304,7 @@ export const query = graphql` | ||||
|   query GalleryPageQuery { | ||||
|     recents: allFile( | ||||
|       filter: { sourceInstanceName: { eq: "gallery" } } | ||||
|       sort: { fields: { imageMeta: { meta: { ModifyDate: DESC } } } } | ||||
|       sort: { fields: { imageMeta: { datePublished: DESC } } } | ||||
|       limit: 7 | ||||
|     ) { | ||||
|       ...GalleryImageFile | ||||
| @@ -307,7 +319,6 @@ export const query = graphql` | ||||
|  | ||||
|   fragment GalleryImageFile on FileConnection { | ||||
|     nodes { | ||||
|       relativePath | ||||
|       base | ||||
|       childImageSharp { | ||||
|         fluid { | ||||
| @@ -324,6 +335,7 @@ export const query = graphql` | ||||
|           vibrantHue | ||||
|           dominantHue | ||||
|           dateTaken | ||||
|           datePublished | ||||
|           meta { | ||||
|             Keywords | ||||
|             Rating | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/utils.ts
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/utils.ts
									
									
									
									
									
								
							| @@ -1,18 +1,23 @@ | ||||
| import React from "react"; | ||||
|  | ||||
| import { pathOr } from "ramda"; | ||||
| // import kebabCase from 'lodash/kebabCase'; | ||||
|  | ||||
| import React from "react"; | ||||
| import { HomepageImage } from "./pages"; | ||||
| import { GalleryImage } from "./pages/photogallery"; | ||||
|  | ||||
| export const getMeta = <T extends GalleryImage | HomepageImage>(image: T) => image.fields?.imageMeta; | ||||
| export const getMeta = <T extends GalleryImage | HomepageImage>(image: T) => | ||||
|   image.fields?.imageMeta; | ||||
|  | ||||
| export const getName = (image: GalleryImage) => | ||||
| image.fields?.imageMeta?.meta?.ObjectName || image.base; | ||||
|   image.fields?.imageMeta?.meta?.ObjectName || image.base; | ||||
|  | ||||
| // some pleasing default colors for SSR and initial hydration | ||||
| export const getVibrant = (image: GalleryImage | HomepageImage) => getMeta(image)?.vibrant; | ||||
| export const getVibrant = (image: GalleryImage | HomepageImage) => | ||||
|   getMeta(image)?.vibrant; | ||||
|  | ||||
| export const hasName = (image: GalleryImage) => Boolean(image.fields?.imageMeta?.meta?.ObjectName); | ||||
| export const hasName = (image: GalleryImage) => | ||||
|   Boolean(image.fields?.imageMeta?.meta?.ObjectName); | ||||
|  | ||||
| export const getAspectRatio = (image: GalleryImage | HomepageImage): number => | ||||
|   image.childImageSharp?.fluid?.aspectRatio ?? 1; | ||||
| @@ -25,7 +30,10 @@ export const getCanonicalSize = (image: GalleryImage) => ({ | ||||
| export const getRgba = (palette: string[], alpha: number) => | ||||
|   `rgba(${palette[0]}, ${palette[1]}, ${palette[2]}, ${alpha || 1})`; | ||||
|  | ||||
| export const getVibrantStyle = (vibrant: Queries.FileFieldsImageMetaVibrant, screenHeight?: number) => ({ | ||||
| export const getVibrantStyle = ( | ||||
|   vibrant: Queries.FileFieldsImageMetaVibrant, | ||||
|   screenHeight?: number | ||||
| ) => ({ | ||||
|   "--muted": vibrant.Muted, | ||||
|   "--dark-muted": vibrant.DarkMuted, | ||||
|   "--light-muted": vibrant.LightMuted, | ||||
| @@ -40,10 +48,12 @@ export const getHelmetSafeBodyStyle = (style: React.CSSProperties) => { | ||||
|   if (typeof window === "undefined") { | ||||
|     return style; | ||||
|   } | ||||
|   return Object.keys(style) | ||||
|   // @ts-ignore | ||||
|     .map((key) => `${key}: ${style[key]};`) | ||||
|     .join(""); | ||||
|   return ( | ||||
|     Object.keys(style) | ||||
|       // @ts-ignore | ||||
|       .map((key) => `${key}: ${style[key]};`) | ||||
|       .join("") | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const gcd = (a: number, b: number): number => { | ||||
| @@ -94,7 +104,10 @@ interface galleryPageUrlProps { | ||||
|   sortKey: string; | ||||
| } | ||||
|  | ||||
| export const getGalleryPageUrl = ({ keyword, sortKey }: galleryPageUrlProps, hash: string) => { | ||||
| export const getGalleryPageUrl = ( | ||||
|   { keyword, sortKey }: galleryPageUrlProps, | ||||
|   hash: string | ||||
| ) => { | ||||
|   const url = new URL( | ||||
|     `${ | ||||
|       typeof window !== "undefined" | ||||
| @@ -121,3 +134,18 @@ export const getGalleryPageUrl = ({ keyword, sortKey }: galleryPageUrlProps, has | ||||
|   } | ||||
|   return url.href.toString().replace(url.origin, ""); | ||||
| }; | ||||
|  | ||||
| export function compareDates<T>( | ||||
|   date_path: readonly string[], | ||||
|   left: T, | ||||
|   right: T | ||||
| ): number { | ||||
|   const d1 = pathOr("", date_path, left); | ||||
|   console.log("🚀 ~ file: utils.ts:129 ~ d1:", d1); | ||||
|   const date1 = new Date(d1); | ||||
|   console.log("🚀 ~ file: utils.ts:146 ~ new Date(d1):", new Date(d1)) | ||||
|   console.log("🚀 ~ file: utils.ts:133 ~ date1:", date1); | ||||
|   const date2 = new Date(pathOr("", date_path, right)); | ||||
|   const diff = -1 * (date1.getTime() - date2.getTime()); | ||||
|   return diff; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user