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

Create basic cards for Images, Links, and File uploads #46

Merged
merged 5 commits into from
Oct 22, 2021
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
20 changes: 17 additions & 3 deletions components/Cards.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ import { useWorkspaceContext } from "../contexts/WorkspaceContext";
import { useConcepts } from "../hooks/concepts";
import { Loader } from './elements'
import NoteCard from "./cards/NoteCard"
import { hasNote } from "../model/concept"
import ImageCard from "./cards/ImageCard"
import FileCard from "./cards/FileCard"
import LinkCard from "./cards/LinkCard"

import {
isConcept,
isBookmarkedLink,
isBookmarkedImage,
isBookmarkedFile,
} from '../utils/rdf';

export function CardsFromConcepts({ concepts, webId, workspaceSlug }) {
return (
<ul className="grid grid-cols-1 gap-6 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3">
{concepts &&
concepts.map((concept) => {
if (hasNote(concept)) {
if (isConcept(concept)) {
return (
<NoteCard
key={asUrl(concept)}
Expand All @@ -20,7 +29,12 @@ export function CardsFromConcepts({ concepts, webId, workspaceSlug }) {
workspaceSlug={workspaceSlug}
/>
);
}
} else if (isBookmarkedImage(concept)) {
return <ImageCard key={asUrl(concept)} image={concept} />;
} else if (isBookmarkedFile(concept)) {
return <FileCard key={asUrl(concept)} file={concept} />;
} else if (isBookmarkedLink(concept))
return <LinkCard key={asUrl(concept)} link={concept} />;
})}
</ul>
);
Expand Down
6 changes: 3 additions & 3 deletions components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function ActiveModal({ title, open, onClose, conceptNames }) {
conceptNames={conceptNames}
/>
);
case 'Bookmark':
case 'Link':
return <NewBookmarkModal open={open} onClose={onClose} />;
case 'File':
return <NewFileModal open={open} onClose={onClose} />;
Expand Down Expand Up @@ -73,8 +73,8 @@ export default function Header({ profile, loggedIn, logout, conceptNames, type }
<div className="uppercase text-gray-300 text-xs mt-2.5 px-4">
Create New
</div>
{(!isPreviewEnv()
? ['Note', 'Bookmark', 'Image', 'File']
{(isPreviewEnv()
? ['Note', 'Link', 'Image', 'File']
: ['Note']
).map((title) => {
return (
Expand Down
45 changes: 45 additions & 0 deletions components/cards/FileCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { asUrl, getDatetime, getStringNoLocale } from '@inrupt/solid-client';
import Link from 'next/link';
import Image from 'next/image';
import { DCTERMS, FOAF } from '@inrupt/vocab-common-rdf';

import { getRelativeTime } from '../../utils/time.js';

export default function FileCard({ file }) {
const url = asUrl(file);
const lastEdit = file && getDatetime(file, DCTERMS.modified);
const title = file && getStringNoLocale(file, DCTERMS.title);

return (
<li className="col-span-1 bg-white rounded-lg overflow-hidden shadow-label list-none">
<Link href={url}>
<a>
<div>
<div className="h-40 border-b-4 border-gray-300 overflow-hidden">
<div className="bg-gradient-to-b from-my-green to-my-dark-green">
<Image
className="transform scale-150 -translate-x-16 translate-y-6 sm:translate-y-9 xl:-translate-y-2"
src="/note-card-splash.png"
width="640"
height="472"
/>
</div>
</div>
<div className="h-56 flex flex-col justify-between p-6">
<h3 className="text-gray-700 text-xl font-bold">{title}</h3>
<p></p>
<footer className="flex flex-row">
<span className="text-my-green text-sm font-semibold mr-3">
File
</span>
<span className="text-gray-300 text-sm">
Last Edited: {getRelativeTime(lastEdit)}
</span>
</footer>
</div>
</div>
</a>
</Link>
</li>
);
}
37 changes: 37 additions & 0 deletions components/cards/ImageCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { asUrl, getStringNoLocale, getDatetime } from '@inrupt/solid-client';
import Link from 'next/link';
import { DCTERMS, FOAF } from '@inrupt/vocab-common-rdf';

import { getRelativeTime } from '../../utils/time.js';

export default function ImageCard({ image }) {
const url = asUrl(image);
const lastEdit = image && getDatetime(image, DCTERMS.modified);
const title = image && getStringNoLocale(image, DCTERMS.title);

return (
<li className="col-span-1 bg-white rounded-lg overflow-hidden shadow-label list-none">
<Link href={url}>
<a>
<div>
<div className="h-40 border-b-4 border-gray-300 overflow-hidden">
<img src={url} className="object-cover h-full " />
</div>
<div className="h-56 flex flex-col justify-between p-6">
<h3 className="text-gray-700 text-xl font-bold">{title}</h3>
<p></p>
<footer className="flex flex-row">
<span className="text-my-green text-sm font-semibold mr-3">
Image
</span>
<span className="text-gray-300 text-sm">
Last Edited: {getRelativeTime(lastEdit)}
</span>
</footer>
</div>
</div>
</a>
</Link>
</li>
);
}
44 changes: 44 additions & 0 deletions components/cards/LinkCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { asUrl, getUrl, getDatetime } from "@inrupt/solid-client";
import Link from "next/link";
import Image from "next/image";
import { DCTERMS, FOAF } from "@inrupt/vocab-common-rdf";

import { getRelativeTime } from '../../utils/time.js';

export default function LinkCard({ link}) {
const url = asUrl(link);
const lastEdit = link && getDatetime(link, DCTERMS.modified);

return (
<li className="col-span-1 bg-white rounded-lg overflow-hidden shadow-label list-none">
<Link href={url}>
<a>
<div>
<div className="h-40 border-b-4 border-gray-300 overflow-hidden">
<div className="bg-gradient-to-b from-my-green to-my-dark-green">
<Image
className="transform scale-150 -translate-x-16 translate-y-6 sm:translate-y-9 xl:-translate-y-2"
src="/note-card-splash.png"
width="640"
height="472"
/>
</div>
</div>
<div className="h-56 flex flex-col justify-between p-6">
<h3 className="text-gray-700 text-xl font-bold">{url}</h3>
<p></p>
<footer className="flex flex-row">
<span className="text-my-green text-sm font-semibold mr-3">
Link
</span>
<span className="text-gray-300 text-sm">
Last Edited: {getRelativeTime(lastEdit)}
</span>
</footer>
</div>
</div>
</a>
</Link>
</li>
);
}
2 changes: 1 addition & 1 deletion components/modals/NewFile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function NewFile({ onClose }) {

const onSubmit = async () => {
if (file) {
const fileUrl = `${fileContainerUri}${file.name}`;
const fileUrl = `${fileContainerUri}${encodeURIComponent(file.name)}`;
await uploadFromFile(file, fileUrl);
const newIndex = addFileToIndex(index, fileUrl, file);
save(newIndex);
Expand Down
14 changes: 7 additions & 7 deletions model/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
createSolidDataset,
} from "@inrupt/solid-client";
import { MY, MIME } from "../vocab";
import { SKOS, RDF, FOAF, DCTERMS } from "@inrupt/vocab-common-rdf";
import { SKOS, RDF, FOAF, DCTERMS } from '@inrupt/vocab-common-rdf';
import * as base58 from "micro-base58";

/*
Expand Down Expand Up @@ -66,12 +66,12 @@ export function addImageToIndex(
url: string,
file: File
): SolidDataset {
const lastModified = new Date(file.lastModified);
const ImageThing = buildThing(createThing({ url }))
.addUrl(RDF.type, MY.SKOS.Bookmark)
.addUrl(RDF.type, FOAF.Image)
.addDatetime(DCTERMS.modified, lastModified)
.addDatetime(DCTERMS.created, lastModified)
.addDatetime(DCTERMS.modified, new Date())
.addDatetime(DCTERMS.created, new Date(file.lastModified))
.addStringNoLocale(DCTERMS.title, file.name)
.addStringNoLocale(DCTERMS.format, file.type)
.build();

Expand All @@ -83,12 +83,12 @@ export function addFileToIndex(
url: string,
file: File
): SolidDataset {
const lastModified = new Date(file.lastModified);
const FileThing = buildThing(createThing({ url }))
.addUrl(RDF.type, MY.SKOS.Bookmark)
.addUrl(RDF.type, MY.FOAF.File)
.addDatetime(DCTERMS.modified, lastModified)
.addDatetime(DCTERMS.created, lastModified)
.addDatetime(DCTERMS.modified, new Date())
.addDatetime(DCTERMS.created, new Date(file.lastModified))
.addStringNoLocale(DCTERMS.title, file.name)
.addStringNoLocale(DCTERMS.format, file.type)
.build();

Expand Down
56 changes: 56 additions & 0 deletions utils/rdf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { US, MY } from "../vocab";
import {
createThing,
addUrl,
setThing,
createSolidDataset,
setDatetime,
getDatetime,
getUrl,
setUrl,
getUrlAll,
Thing,
IriString,
Iri,
} from '@inrupt/solid-client';
import { FOAF, DCTERMS, RDF } from "@inrupt/vocab-common-rdf";

export function hasUSNote(thing: Thing): boolean {
return !!getUrl(thing, US.storedAt);
}

export function isConcept(thing: Thing): boolean {
return hasUSNote(thing);
}

export function hasRDFTypes(thing: Thing, ts: IriString[]): boolean {
const types = getUrlAll(thing, RDF.type);
let hasAllTypes = true;
for (let t of ts) {
hasAllTypes = hasAllTypes && types.includes(t);
}
return hasAllTypes;
}

export function hasRDFType(thing: Thing, t: IriString): boolean {
return hasRDFTypes(thing, [t]);
}

export function isBookmark(thing: Thing): boolean {
return hasRDFType(thing, MY.SKOS.Bookmark);
}

export function isBookmarkedImage(thing: Thing): boolean {
// Inrupt vocabs return NamedNodes,
// ours currently only returns the IRI
// so grab the IRI from the inrupt vocab so this works
return hasRDFTypes(thing, [MY.SKOS.Bookmark, FOAF.Image.iri.value]);
}

export function isBookmarkedLink(thing: Thing): boolean {
return hasRDFTypes(thing, [MY.SKOS.Bookmark, MY.FOAF.Link]);
}

export function isBookmarkedFile(thing: Thing): boolean {
return hasRDFTypes(thing, [MY.SKOS.Bookmark, MY.FOAF.File]);
}