www/server: introduce share mode

This commit is contained in:
2023-11-07 12:39:48 +01:00
parent 6282583d92
commit 226b92c347
8 changed files with 228 additions and 34 deletions

View File

@@ -99,7 +99,12 @@ export default function TranscriptDetails(details: TranscriptDetails) {
/>
</div>
<div className="flex-grow max-w-full">
<ShareLink />
<ShareLink
protectedPath={protectedPath}
transcriptId={transcript?.response?.id}
userId={transcript?.response?.userId}
shareMode={transcript?.response?.shareMode}
/>
</div>
</section>
</div>

View File

@@ -1,15 +1,37 @@
import React, { useState, useRef, useEffect, use } from "react";
import { featureEnabled } from "../domainContext";
import getApi from "../../lib/getApi";
import { useFiefUserinfo } from "@fief/fief/nextjs/react";
import SelectSearch from "react-select-search";
import "react-select-search/style.css";
import "../../styles/button.css";
import "../../styles/form.scss";
const ShareLink = () => {
type ShareLinkProps = {
protectedPath: boolean;
transcriptId: string;
userId: string | null;
shareMode: string;
};
const ShareLink = (props: ShareLinkProps) => {
const [isCopied, setIsCopied] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const [currentUrl, setCurrentUrl] = useState<string>("");
const requireLogin = featureEnabled("requireLogin");
const [isOwner, setIsOwner] = useState(false);
const [shareMode, setShareMode] = useState(props.shareMode);
const api = getApi(props.protectedPath);
const userinfo = useFiefUserinfo();
useEffect(() => {
setCurrentUrl(window.location.href);
}, []);
useEffect(() => {
setIsOwner(!!(requireLogin && userinfo?.sub === props.userId));
}, [userinfo, props.userId]);
const handleCopyClick = () => {
if (inputRef.current) {
let text_to_copy = inputRef.current.value;
@@ -23,6 +45,16 @@ const ShareLink = () => {
}
};
const updateShareMode = async (selectedShareMode: string) => {
if (!api) return;
const updatedTranscript = await api.v1TranscriptUpdate({
transcriptId: props.transcriptId,
updateTranscript: {
shareMode: selectedShareMode,
},
});
setShareMode(updatedTranscript.shareMode);
};
const privacyEnabled = featureEnabled("privacy");
return (
@@ -30,18 +62,50 @@ const ShareLink = () => {
className="p-2 md:p-4 rounded"
style={{ background: "rgba(96, 165, 250, 0.2)" }}
>
{privacyEnabled ? (
{requireLogin && (
<p className="text-sm mb-2">
You can share this link with others. Anyone with the link will have
access to the page, including the full audio recording, for the next 7
days.
</p>
) : (
<p className="text-sm mb-2">
You can share this link with others. Anyone with the link will have
access to the page, including the full audio recording.
{shareMode === "private" && (
<p>This transcript is only accessible by you.</p>
)}
{shareMode === "semi-private" && (
<p>This transcript is accessible by any authenticated users.</p>
)}
{shareMode === "public" && (
<p>This transcript is accessible by anyone.</p>
)}
{isOwner && api && (
<p>
<SelectSearch
className="select-search--top select-search"
options={[
{ name: "Private", value: "private" },
{ name: "Semi-private", value: "semi-private" },
{ name: "Public", value: "public" },
]}
value={shareMode}
onChange={updateShareMode}
/>
</p>
)}
</p>
)}
{!requireLogin && (
<>
{privacyEnabled ? (
<p className="text-sm mb-2">
You can share this link with others. Anyone with the link will
have access to the page, including the full audio recording, for
the next 7 days.
</p>
) : (
<p className="text-sm mb-2">
You can share this link with others. Anyone with the link will
have access to the page, including the full audio recording.
</p>
)}
</>
)}
<div className="flex items-center">
<input
type="text"

View File

@@ -25,6 +25,12 @@ export interface GetTranscript {
* @memberof GetTranscript
*/
id: any | null;
/**
*
* @type {any}
* @memberof GetTranscript
*/
userId: any | null;
/**
*
* @type {any}
@@ -73,6 +79,12 @@ export interface GetTranscript {
* @memberof GetTranscript
*/
createdAt: any | null;
/**
*
* @type {any}
* @memberof GetTranscript
*/
shareMode?: any | null;
/**
*
* @type {any}
@@ -93,6 +105,7 @@ export interface GetTranscript {
export function instanceOfGetTranscript(value: object): boolean {
let isInstance = true;
isInstance = isInstance && "id" in value;
isInstance = isInstance && "userId" in value;
isInstance = isInstance && "name" in value;
isInstance = isInstance && "status" in value;
isInstance = isInstance && "locked" in value;
@@ -120,6 +133,7 @@ export function GetTranscriptFromJSONTyped(
}
return {
id: json["id"],
userId: json["user_id"],
name: json["name"],
status: json["status"],
locked: json["locked"],
@@ -128,6 +142,7 @@ export function GetTranscriptFromJSONTyped(
shortSummary: json["short_summary"],
longSummary: json["long_summary"],
createdAt: json["created_at"],
shareMode: !exists(json, "share_mode") ? undefined : json["share_mode"],
sourceLanguage: json["source_language"],
targetLanguage: json["target_language"],
};
@@ -142,6 +157,7 @@ export function GetTranscriptToJSON(value?: GetTranscript | null): any {
}
return {
id: value.id,
user_id: value.userId,
name: value.name,
status: value.status,
locked: value.locked,
@@ -150,6 +166,7 @@ export function GetTranscriptToJSON(value?: GetTranscript | null): any {
short_summary: value.shortSummary,
long_summary: value.longSummary,
created_at: value.createdAt,
share_mode: value.shareMode,
source_language: value.sourceLanguage,
target_language: value.targetLanguage,
};

View File

@@ -49,6 +49,12 @@ export interface UpdateTranscript {
* @memberof UpdateTranscript
*/
longSummary?: any | null;
/**
*
* @type {any}
* @memberof UpdateTranscript
*/
shareMode?: any | null;
}
/**
@@ -81,6 +87,7 @@ export function UpdateTranscriptFromJSONTyped(
longSummary: !exists(json, "long_summary")
? undefined
: json["long_summary"],
shareMode: !exists(json, "share_mode") ? undefined : json["share_mode"],
};
}
@@ -97,5 +104,6 @@ export function UpdateTranscriptToJSON(value?: UpdateTranscript | null): any {
title: value.title,
short_summary: value.shortSummary,
long_summary: value.longSummary,
share_mode: value.shareMode,
};
}

View File

@@ -35,3 +35,8 @@ body.is-light-mode .input-container {
max-width: 100%;
width: auto;
}
body .select-search-container .select-search--top.select-search-select {
top: auto;
bottom: 46px;
}