mirror of
https://github.com/LukeHagar/plexjs.git
synced 2025-12-06 04:20:46 +00:00
## Typescript SDK Changes:
* `plex-api.libraryPlaylists.addPlaylistItems()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getMetadataHubs()`: * `request.onlyTransient` **Changed** * `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryCollections.moveCollectionItem()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryCollections.deleteCollectionItem()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryCollections.addCollectionItems()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.content.getSonicallySimilar()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.butler.stopTask()`: `request` **Changed** **Breaking** ⚠️ * `plex-api.butler.startTask()`: `request` **Changed** **Breaking** ⚠️ * `plex-api.content.getSonicPath()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.downloadQueue.getItemDecision()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getAllHubs()`: * `request.onlyTransient` **Changed** * `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getContinueWatching()`: `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getPromotedHubs()`: `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.content.getAllLeaves()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getPostplayHubs()`: * `request.onlyTransient` **Changed** * `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getRelatedHubs()`: * `request.onlyTransient` **Changed** * `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.hubs.getSectionHubs()`: * `request.onlyTransient` **Changed** * `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.content.listContent()`: * `request` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.content.getAlbums()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.search.searchHubs()`: `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.search.voiceSearchHubs()`: * `request.type` **Changed** **Breaking** ⚠️ * `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getLibraryItems()`: * `request.mediaQuery` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.ingestTransientItem()`: * `request` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getLibraryMatches()`: * `request` **Changed** **Breaking** ⚠️ * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.content.getMetadataItem()`: * `request` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getSections()`: `response.mediacontainer.directory.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.addSection()`: * `request` **Changed** * `response.mediacontainer.directory.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getTags()`: * `request.type` **Changed** **Breaking** ⚠️ * `plex-api.content.getCollectionItems()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getAllItemLeaves()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.status.listSessions()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.movePlayQueueItem()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getExtras()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.deletePlayQueueItem()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.unshuffle()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.listMatches()`: * `request.manual` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.listSonicallySimilar()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.resetPlayQueue()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getRelatedItems()`: `response.mediacontainer.hub.[].metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.listSimilar()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.clearPlayQueue()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getItemTree()`: `response.mediacontainer.metadataItem.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.addToPlayQueue()`: * `request.next` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.getPlayQueue()`: * `request` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryPlaylists.movePlaylistItem()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getPerson()`: `response.mediacontainer.directory.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.listPersonMedia()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryPlaylists.getPlaylistGeneratorItems()`: `response.mediacontainer.metadata` **Changed** **Breaking** ⚠️ * `plex-api.library.getLibraryDetails()`: * `request.includeDetails` **Changed** * `response.mediacontainer.directory.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryPlaylists.modifyPlaylistGenerator()`: * `request.item` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.autocomplete()`: * `request.mediaQuery` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getCollections()`: * `request.mediaQuery` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.getCommon()`: * `request.mediaQuery` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryPlaylists.deletePlaylistItem()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryPlaylists.clearPlaylistItems()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playQueue.shuffle()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.libraryPlaylists.createPlaylist()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playlist.getPlaylistItems()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playlist.getPlaylist()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.collections.createCollection()`: * `request.type` **Changed** **Breaking** ⚠️ * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.dvRs.tuneChannel()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.liveTv.getSessions()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.liveTv.getLiveTvSession()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.playlist.listPlaylists()`: `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.getAllSubscriptions()`: * `request` **Changed** * `response.mediacontainer.mediaSubscription.[].mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.createSubscription()`: `response.mediacontainer.mediaSubscription.[].mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.getScheduledRecordings()`: `response.mediacontainer.mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.getTemplate()`: `response.mediacontainer.subscriptionTemplate.[].mediaSubscription.[].mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.getSubscription()`: * `request` **Changed** * `response.mediacontainer.mediaSubscription.[].mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.editSubscriptionPreferences()`: `response.mediacontainer.mediaSubscription.[].mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.subscriptions.reorderSubscription()`: `response.mediacontainer.mediaSubscription.[].mediaGrabOperation.[].metadata` **Changed** **Breaking** ⚠️ * `plex-api.transcoder.makeDecision()`: * `request` **Changed** * `response.mediacontainer.metadata.[]` **Changed** **Breaking** ⚠️ * `plex-api.library.refreshItemsMetadata()`: * `request.markUpdated` **Changed** * `plex-api.authentication.postUsersSignInData()`: **Added** * `plex-api.transcoder.startTranscodeSession()`: `request` **Changed** * `plex-api.devices.modifyDevice()`: * `request.enabled` **Changed** * `plex-api.library.getMediaPart()`: * `request.download` **Changed** * `plex-api.library.detectIntros()`: * `request.force` **Changed** * `plex-api.library.refreshSection()`: * `request.force` **Changed** * `plex-api.libraryPlaylists.uploadPlaylist()`: * `request.force` **Changed** * `plex-api.library.deleteMediaItem()`: * `request.proxy` **Changed** * `plex-api.authentication.getTokenDetails()`: **Added** * `plex-api.library.getFirstCharacters()`: * `request.mediaQuery` **Changed** * `plex-api.library.updateItems()`: * `request.field.locked` **Changed** * `plex-api.library.deleteLibrarySection()`: * `request.async` **Changed** * `plex-api.library.setStreamSelection()`: * `request.allParts` **Changed** * `plex-api.playQueue.createPlayQueue()`: `request` **Changed** * `plex-api.library.getAugmentationStatus()`: * `request.wait` **Changed** * `plex-api.library.detectVoiceActivity()`: `request` **Changed** * `plex-api.transcoder.transcodeImage()`: `request` **Changed** * `plex-api.transcoder.transcodeSubtitles()`: `request` **Changed** * `plex-api.library.addSubtitles()`: `request` **Changed** * `plex-api.library.getStream()`: * `request.autoAdjustSubtitle` **Changed** * `plex-api.library.startBifGeneration()`: * `request.force` **Changed** * `plex-api.library.detectCredits()`: `request` **Changed** * `plex-api.ultraBlur.getImage()`: * `request.noise` **Changed** * `plex-api.library.generateThumbs()`: * `request.force` **Changed** * `plex-api.updater.applyUpdates()`: `request` **Changed** * `plex-api.updater.checkUpdates()`: * `request.download` **Changed** * `plex-api.library.deleteMetadataItem()`: * `request.proxy` **Changed** * `plex-api.library.optimizeDatabase()`: * `request.async` **Changed** * `plex-api.hubs.updateHubVisibility()`: `request` **Changed** * `plex-api.hubs.createCustomHub()`: `request` **Changed** * `plex-api.library.getSectionImage()`: * `request.mediaQuery` **Changed** * `plex-api.downloadQueue.addDownloadQueueItems()`: `request` **Changed** * `plex-api.timeline.report()`: `request` **Changed** * `plex-api.general.getSourceConnectionInformation()`: * `request.refresh` **Changed** * `plex-api.plex.getServerResources()`: **Added** * `plex-api.users.getUsers()`: **Added**
This commit is contained in:
@@ -30,7 +30,9 @@ Creates a download queue for this client if one doesn't exist, or returns the ex
|
||||
```typescript
|
||||
import { PlexAPI } from "@lukehagar/plexjs";
|
||||
|
||||
const plexAPI = new PlexAPI();
|
||||
const plexAPI = new PlexAPI({
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const result = await plexAPI.downloadQueue.createDownloadQueue();
|
||||
@@ -51,7 +53,9 @@ import { downloadQueueCreateDownloadQueue } from "@lukehagar/plexjs/funcs/downlo
|
||||
|
||||
// Use `PlexAPICore` for best tree-shaking performance.
|
||||
// You can create one instance of it to use across an application.
|
||||
const plexAPI = new PlexAPICore();
|
||||
const plexAPI = new PlexAPICore({
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
const res = await downloadQueueCreateDownloadQueue(plexAPI);
|
||||
@@ -110,6 +114,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -146,6 +151,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -194,7 +200,7 @@ Add items to the download queue
|
||||
<!-- UsageSnippet language="typescript" operationID="addDownloadQueueItems" method="post" path="/downloadQueue/{queueId}/add" -->
|
||||
```typescript
|
||||
import { PlexAPI } from "@lukehagar/plexjs";
|
||||
import { Accepts, AdvancedSubtitles, BoolInt, LocationParameter, Protocol } from "@lukehagar/plexjs/sdk/models/shared";
|
||||
import { Accepts, AdvancedSubtitles, BoolInt, LocationParameter, ProtocolParameter } from "@lukehagar/plexjs/sdk/models/shared";
|
||||
|
||||
const plexAPI = new PlexAPI({
|
||||
accepts: Accepts.ApplicationXml,
|
||||
@@ -208,6 +214,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -220,13 +227,13 @@ async function run() {
|
||||
advancedSubtitles: AdvancedSubtitles.Burn,
|
||||
audioBoost: 50,
|
||||
audioChannelCount: 5,
|
||||
autoAdjustQuality: BoolInt.One,
|
||||
autoAdjustSubtitle: BoolInt.One,
|
||||
directPlay: BoolInt.One,
|
||||
directStream: BoolInt.One,
|
||||
directStreamAudio: BoolInt.One,
|
||||
disableResolutionRotation: BoolInt.One,
|
||||
hasMDE: BoolInt.One,
|
||||
autoAdjustQuality: BoolInt.True,
|
||||
autoAdjustSubtitle: BoolInt.True,
|
||||
directPlay: BoolInt.True,
|
||||
directStream: BoolInt.True,
|
||||
directStreamAudio: BoolInt.True,
|
||||
disableResolutionRotation: BoolInt.True,
|
||||
hasMDE: BoolInt.True,
|
||||
location: LocationParameter.Wan,
|
||||
mediaBufferSize: 102400,
|
||||
mediaIndex: 0,
|
||||
@@ -236,7 +243,7 @@ async function run() {
|
||||
path: "/library/metadata/151671",
|
||||
peakBitrate: 12000,
|
||||
photoResolution: "1080x1080",
|
||||
protocol: Protocol.Dash,
|
||||
protocol: ProtocolParameter.Dash,
|
||||
secondsPerSegment: 5,
|
||||
subtitleSize: 50,
|
||||
videoBitrate: 12000,
|
||||
@@ -257,7 +264,7 @@ The standalone function version of this method:
|
||||
```typescript
|
||||
import { PlexAPICore } from "@lukehagar/plexjs/core.js";
|
||||
import { downloadQueueAddDownloadQueueItems } from "@lukehagar/plexjs/funcs/downloadQueueAddDownloadQueueItems.js";
|
||||
import { Accepts, AdvancedSubtitles, BoolInt, LocationParameter, Protocol } from "@lukehagar/plexjs/sdk/models/shared";
|
||||
import { Accepts, AdvancedSubtitles, BoolInt, LocationParameter, ProtocolParameter } from "@lukehagar/plexjs/sdk/models/shared";
|
||||
|
||||
// Use `PlexAPICore` for best tree-shaking performance.
|
||||
// You can create one instance of it to use across an application.
|
||||
@@ -273,6 +280,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -285,13 +293,13 @@ async function run() {
|
||||
advancedSubtitles: AdvancedSubtitles.Burn,
|
||||
audioBoost: 50,
|
||||
audioChannelCount: 5,
|
||||
autoAdjustQuality: BoolInt.One,
|
||||
autoAdjustSubtitle: BoolInt.One,
|
||||
directPlay: BoolInt.One,
|
||||
directStream: BoolInt.One,
|
||||
directStreamAudio: BoolInt.One,
|
||||
disableResolutionRotation: BoolInt.One,
|
||||
hasMDE: BoolInt.One,
|
||||
autoAdjustQuality: BoolInt.True,
|
||||
autoAdjustSubtitle: BoolInt.True,
|
||||
directPlay: BoolInt.True,
|
||||
directStream: BoolInt.True,
|
||||
directStreamAudio: BoolInt.True,
|
||||
disableResolutionRotation: BoolInt.True,
|
||||
hasMDE: BoolInt.True,
|
||||
location: LocationParameter.Wan,
|
||||
mediaBufferSize: 102400,
|
||||
mediaIndex: 0,
|
||||
@@ -301,7 +309,7 @@ async function run() {
|
||||
path: "/library/metadata/151671",
|
||||
peakBitrate: 12000,
|
||||
photoResolution: "1080x1080",
|
||||
protocol: Protocol.Dash,
|
||||
protocol: ProtocolParameter.Dash,
|
||||
secondsPerSegment: 5,
|
||||
subtitleSize: 50,
|
||||
videoBitrate: 12000,
|
||||
@@ -364,6 +372,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -400,6 +409,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -462,6 +472,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -499,6 +510,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -562,6 +574,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -599,6 +612,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -659,6 +673,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -700,6 +715,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -767,6 +783,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -808,6 +825,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -875,6 +893,7 @@ const plexAPI = new PlexAPI({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
@@ -916,6 +935,7 @@ const plexAPI = new PlexAPICore({
|
||||
deviceVendor: "Roku",
|
||||
deviceName: "Living Room TV",
|
||||
marketplace: "googlePlay",
|
||||
token: "<YOUR_API_KEY_HERE>",
|
||||
});
|
||||
|
||||
async function run() {
|
||||
|
||||
Reference in New Issue
Block a user