diff --git a/config.sample.json b/config.sample.json index 5ddc34b3fc..973bb67a02 100644 --- a/config.sample.json +++ b/config.sample.json @@ -47,5 +47,6 @@ "participant_limit": 8, "brand": "Element Call" }, - "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx" + "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx", + "giphy_api_key": "x" } diff --git a/res/css/views/gifpicker/_GifPicker.pcss b/res/css/views/gifpicker/_GifPicker.pcss index 36e03d29f3..9eef09a9c4 100644 --- a/res/css/views/gifpicker/_GifPicker.pcss +++ b/res/css/views/gifpicker/_GifPicker.pcss @@ -102,7 +102,12 @@ Please see LICENSE files in the repository root for full details. .mx_GifPicker_search_icon { width: 16px; + height: 16px; + border: none; + background-color: inherit; margin: 8px; + padding: 8px; + align-self: center; } .mx_GifPicker_search_icon:not(.mx_GifPicker_search_clear) { diff --git a/src/IConfigOptions.ts b/src/IConfigOptions.ts index 8b88a18075..7ebbbf3f2b 100644 --- a/src/IConfigOptions.ts +++ b/src/IConfigOptions.ts @@ -55,6 +55,7 @@ export interface IConfigOptions { force_verification?: boolean; // if true, users must verify new logins map_style_url?: string; // for location-shared maps + giphy_api_key?: string; // gif picker embedded_pages?: { welcome_url?: string; diff --git a/src/components/views/gifpicker/GifPicker.tsx b/src/components/views/gifpicker/GifPicker.tsx index 2fe3f31d26..bffbab7676 100644 --- a/src/components/views/gifpicker/GifPicker.tsx +++ b/src/components/views/gifpicker/GifPicker.tsx @@ -10,21 +10,28 @@ import dis from "../../../dispatcher/dispatcher"; import { Action } from "../../../dispatcher/actions"; import { ComposerInsertPayload } from "../../../dispatcher/payloads/ComposerInsertPayload"; import { IEventRelation } from "matrix-js-sdk/src/matrix"; +import { getGiphyApiKey } from "../../../utils/WellKnownUtils"; +import { TimelineRenderingType } from "../../../contexts/RoomContext"; -const GIPHY_API_KEY = "x"; // TODO: Move to config -const gf = new GiphyFetch(GIPHY_API_KEY); +const GIPHY_API_KEY = getGiphyApiKey(); +const gf = new GiphyFetch(GIPHY_API_KEY!); interface IProps { onGifSelect: (url: string) => void; onFinished: () => void; roomId: string; relation?: IEventRelation; - timelineRenderingType: string; + timelineRenderingType: TimelineRenderingType; } export const GifPicker: React.FC = ({ onGifSelect, onFinished, roomId, relation, timelineRenderingType }) => { const [searchQuery, setSearchQuery] = useState(""); - + + if (!GIPHY_API_KEY) { + console.error("GIPHY API key is missing in the configuration."); + return null; // Return null if the API key is not configured + } + const fetchGifs = (offset: number) => { if (!searchQuery) { return gf.trending({ offset, limit: 10 }); @@ -53,8 +60,8 @@ export const GifPicker: React.FC = ({ onGifSelect, onFinished, roomId, r [file], roomId, relation, - MatrixClientPeg.get(), - timelineRenderingType + MatrixClientPeg.safeGet(), + timelineRenderingType as TimelineRenderingType ); onFinished(); diff --git a/src/components/views/rooms/GifButton.tsx b/src/components/views/rooms/GifButton.tsx index 32f2255f2b..1bf9651bef 100644 --- a/src/components/views/rooms/GifButton.tsx +++ b/src/components/views/rooms/GifButton.tsx @@ -15,6 +15,7 @@ import GifPicker from "../gifpicker/GifPicker"; import { CollapsibleButton } from "./CollapsibleButton"; import { OverflowMenuContext } from "./MessageComposerButtons"; import { IEventRelation } from "matrix-js-sdk/src/matrix"; +import { TimelineRenderingType } from "../../../contexts/RoomContext"; interface IGifButtonProps { addGif: (unicode: string) => boolean; @@ -22,7 +23,7 @@ interface IGifButtonProps { className?: string; roomId: string; relation?: IEventRelation; - timelineRenderingType: string; + timelineRenderingType: TimelineRenderingType; } export function GifButton({ addGif, menuPosition, className, roomId, relation, timelineRenderingType }: IGifButtonProps): JSX.Element { diff --git a/src/utils/WellKnownUtils.ts b/src/utils/WellKnownUtils.ts index b2af51e2c3..33d27166e2 100644 --- a/src/utils/WellKnownUtils.ts +++ b/src/utils/WellKnownUtils.ts @@ -8,12 +8,14 @@ Please see LICENSE files in the repository root for full details. import { type IClientWellKnown, type MatrixClient } from "matrix-js-sdk/src/matrix"; import { UnstableValue } from "matrix-js-sdk/src/NamespacedValue"; +import SdkConfig from "../SdkConfig"; const CALL_BEHAVIOUR_WK_KEY = "io.element.call_behaviour"; const E2EE_WK_KEY = "io.element.e2ee"; const E2EE_WK_KEY_DEPRECATED = "im.vector.riot.e2ee"; export const TILE_SERVER_WK_KEY = new UnstableValue("m.tile_server", "org.matrix.msc3488.tile_server"); const EMBEDDED_PAGES_WK_PROPERTY = "io.element.embedded_pages"; +export const GIPHY_WK_KEY = "" /* eslint-disable camelcase */ export interface ICallBehaviourWellKnown { @@ -38,6 +40,10 @@ export interface ITileServerWellKnown { map_style_url?: string; } +export interface IGiphyKeyWellKnown { + giphy_api_key?: string; +} + export interface IEmbeddedPagesWellKnown { home_url?: string; } @@ -67,6 +73,14 @@ export function tileServerFromWellKnown(clientWellKnown?: IClientWellKnown | und return clientWellKnown?.[TILE_SERVER_WK_KEY.name] ?? clientWellKnown?.[TILE_SERVER_WK_KEY.altName]; } +export function getGiphyKeyWellKnown(matrixClient: MatrixClient): IGiphyKeyWellKnown | undefined { + return giphyKeyFromWellKnown(matrixClient.getClientWellKnown()); +} + +export function giphyKeyFromWellKnown(clientWellKnown?: IClientWellKnown | undefined): IGiphyKeyWellKnown { + return clientWellKnown?.[TILE_SERVER_WK_KEY.name] ?? clientWellKnown?.[TILE_SERVER_WK_KEY.altName]; +} + export function getEmbeddedPagesWellKnown(matrixClient: MatrixClient | undefined): IEmbeddedPagesWellKnown | undefined { return embeddedPagesFromWellKnown(matrixClient?.getClientWellKnown()); } @@ -99,3 +113,8 @@ export function getSecureBackupSetupMethods(matrixClient: MatrixClient): SecureB } return wellKnown["secure_backup_setup_methods"]; } + +export function getGiphyApiKey(): string | undefined { + const config = SdkConfig.get(); + return config?.giphy_api_key; +} diff --git a/tsconfig.json b/tsconfig.json index 854af09239..e5af949e1c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "allowImportingTsExtensions": true, + "noEmit": true, "experimentalDecorators": false, "emitDecoratorMetadata": false, "resolveJsonModule": true, diff --git a/webpack.config.js b/webpack.config.js index e0d7d4fe93..ff58632f43 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -599,6 +599,7 @@ module.exports = (env, argv) => { templateParameters: { og_image_url: ogImageUrl, csp_extra_source: process.env.CSP_EXTRA_SOURCE ?? "", + csp_img_src: "'self' blob: data: https://media.giphy.com media.giphy.com https://media2.giphy.com media2.giphy.com https://media3.giphy.com media3.giphy.com", }, }),