.logged-in-more {
margin-right: 20px;
- my-global-icon {
- @include apply-svg-color(var(--mainBackgroundColor));
-
+ my-global-icon.dropdown-toggle {
cursor: pointer;
&::after {
border: none;
}
+
+ /deep/ {
+ @include apply-svg-color(var(--menuForegroundColor));
+ }
}
.dropdown-item {
@include dropdown-with-icon-item;
my-global-icon {
- @include apply-svg-color(var(--mainForegroundColor));
-
width: 22px;
height: 22px;
.more-icon {
width: 21px;
+
+ /deep/ {
+ @include apply-svg-color(var(--mainForegroundColor));
+ }
}
&.small {
areActionsDisplayed (actions: DropdownAction<T>[], entry: T) {
return actions.some(a => a.isDisplayed === undefined || a.isDisplayed(entry))
}
-
- handleClick (event: Event, action: DropdownAction<T>) {
- event.preventDefault()
-
- // action.handler(entry)
- }
}
// Don't care if dirty on force check
const isDirty = control.dirty || forceCheck === true
- if (control && isDirty && !control.valid) {
+ if (control && isDirty && control.enabled && !control.valid) {
const messages = validationMessages[ field ]
for (const key of Object.keys(control.errors)) {
formErrors[ field ] += messages[ key ] + ' '
table {
font-size: 14px;
+ color: var(--mainForegroundColor);
.label {
font-weight: $font-semibold;
.glyphicon-remove {
color: $red;
}
-}
\ No newline at end of file
+}
styleUrls: ['./remote-subscribe.component.scss']
})
export class RemoteSubscribeComponent extends FormReactive implements OnInit {
- @Input() account: string
+ @Input() uri: string
@Input() interact = false
@Input() showHelp = false
fetch(`https://${hostname}/.well-known/webfinger?resource=acct:${username}@${hostname}`)
.then(response => response.json())
.then(data => new Promise((resolve, reject) => {
+ console.log(data)
+
if (data && Array.isArray(data.links)) {
- const link: {
- template: string
- } = data.links.find((link: any) =>
- link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe')
+ const link: { template: string } = data.links.find((link: any) => {
+ return link && typeof link.template === 'string' && link.rel === 'http://ostatus.org/schema/1.0/subscribe'
+ })
if (link && link.template.includes('{uri}')) {
- resolve(link.template.replace('{uri}', `acct:${this.account}`))
+ resolve(link.template.replace('{uri}', encodeURIComponent(this.uri)))
}
}
reject()
}))
.then(window.open)
- .catch(() => window.open(`https://${hostname}/authorize_interaction?acct=${this.account}`))
+ .catch(err => console.error(err))
}
}
</button>
<button class="dropdown-item" i18n>Subscribe with a Mastodon account:</button>
- <my-remote-subscribe showHelp="true" account="{{ uriAccount }}"></my-remote-subscribe>
+ <my-remote-subscribe showHelp="true" [uri]="channelUri"></my-remote-subscribe>
<div class="dropdown-divider"></div>
</div>
</div>
-</div>
\ No newline at end of file
+</div>
private videoService: VideoService
) { }
- get uri () {
+ get channelHandle () {
return this.videoChannel.name + '@' + this.videoChannel.host
}
- get uriAccount () {
- return this.videoChannel.ownerAccount.name + '@' + this.videoChannel.host
+ get channelUri () {
+ return this.videoChannel.url
}
ngOnInit () {
if (this.isUserLoggedIn()) {
- this.userSubscriptionService.doesSubscriptionExist(this.uri)
+ this.userSubscriptionService.doesSubscriptionExist(this.channelHandle)
.subscribe(
- res => this.subscribed = res[this.uri],
+ res => this.subscribed = res[this.channelHandle],
err => this.notifier.error(err.message)
)
}
localSubscribe () {
- this.userSubscriptionService.addSubscription(this.uri)
+ this.userSubscriptionService.addSubscription(this.channelHandle)
.subscribe(
() => {
this.subscribed = true
}
localUnsubscribe () {
- this.userSubscriptionService.deleteSubscription(this.uri)
+ this.userSubscriptionService.deleteSubscription(this.channelHandle)
.subscribe(
() => {
this.subscribed = false
}
private buildActions () {
- this.videoActions = []
-
- if (this.authService.isLoggedIn()) {
- this.videoActions.push([
+ this.videoActions = [
+ [
{
label: this.i18n('Save to playlist'),
handler: () => this.playlistDropdown.toggle(),
- isDisplayed: () => this.displayOptions.playlist,
+ isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.playlist,
iconName: 'playlist-add'
}
- ])
-
- this.videoActions.push([
+ ],
+ [
{
label: this.i18n('Download'),
handler: () => this.showDownloadModal(),
label: this.i18n('Update'),
linkBuilder: ({ video }) => [ '/videos/update', video.uuid ],
iconName: 'edit',
- isDisplayed: () => this.displayOptions.update && this.isVideoUpdatable()
+ isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.update && this.isVideoUpdatable()
},
{
label: this.i18n('Blacklist'),
handler: () => this.showBlacklistModal(),
iconName: 'no',
- isDisplayed: () => this.displayOptions.blacklist && this.isVideoBlacklistable()
+ isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoBlacklistable()
},
{
label: this.i18n('Unblacklist'),
handler: () => this.unblacklistVideo(),
iconName: 'undo',
- isDisplayed: () => this.displayOptions.blacklist && this.isVideoUnblacklistable()
+ isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.blacklist && this.isVideoUnblacklistable()
},
{
label: this.i18n('Delete'),
handler: () => this.removeVideo(),
- isDisplayed: () => this.displayOptions.delete && this.isVideoRemovable(),
+ isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.delete && this.isVideoRemovable(),
iconName: 'delete'
}
- ])
-
- this.videoActions.push([
+ ],
+ [
{
label: this.i18n('Report'),
handler: () => this.showReportModal(),
- isDisplayed: () => this.displayOptions.report,
+ isDisplayed: () => this.authService.isLoggedIn() && this.displayOptions.report,
iconName: 'alert'
}
- ])
- }
+ ]
+ ]
}
}
}
private trackPrivacyChange () {
- // We will update the "support" field depending on the channel
+ // We will update the schedule input and the wait transcoding checkbox validators
this.form.controls[ 'privacy' ]
.valueChanges
.pipe(map(res => parseInt(res.toString(), 10)))
<span i18n>
If you have an account on Mastodon or Pleroma, you can open it directly in their interface:
</span>
- <my-remote-subscribe [interact]="true" [account]="getUrl()"></my-remote-subscribe>
+ <my-remote-subscribe [interact]="true" [uri]="getUri()"></my-remote-subscribe>
</div>
<div class="modal-footer inputs">
<span i18n class="action-button action-button-cancel" role="button" (click)="hideVisitorModal()">
import { Video } from '../../../shared/video/video.model'
import { VideoComment } from './video-comment.model'
import { VideoCommentService } from './video-comment.service'
-import { I18n } from '@ngx-translate/i18n-polyfill'
import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
import { VideoCommentValidatorsService } from '@app/shared/forms/form-validators/video-comment-validators.service'
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
private videoCommentService: VideoCommentService,
private authService: AuthService,
private modalService: NgbModal,
- private router: Router,
- private i18n: I18n
+ private router: Router
) {
super()
}
return this.form.value['text']
}
- getUrl () {
+ getUri () {
return window.location.href
}
import { createVideoMiniatureFromExisting } from '../../../lib/thumbnail'
import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
import { ThumbnailModel } from '../../../models/video/thumbnail'
+import { UserModel } from '../../../models/account/user'
const auditLogger = auditLoggerFactory('video-imports')
const videoImportsRouter = express.Router()
previewModel,
videoChannel: res.locals.videoChannel,
tags,
- videoImportAttributes
+ videoImportAttributes,
+ user
})
// Create job to import the video
userId: user.id
}
const videoImport = await insertIntoDB({
- video: video,
+ video,
thumbnailModel,
previewModel,
videoChannel: res.locals.videoChannel,
tags,
- videoImportAttributes
+ videoImportAttributes,
+ user
})
// Create job to import the video
previewModel: ThumbnailModel,
videoChannel: VideoChannelModel,
tags: string[],
- videoImportAttributes: Partial<VideoImportModel>
+ videoImportAttributes: Partial<VideoImportModel>,
+ user: UserModel
}): Bluebird<VideoImportModel> {
- let { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes } = parameters
+ const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
return sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { transaction: t }
if (thumbnailModel) await videoCreated.addAndSaveThumbnail(thumbnailModel, t)
if (previewModel) await videoCreated.addAndSaveThumbnail(previewModel, t)
- await autoBlacklistVideoIfNeeded(video, videoChannel.Account.User, t)
+ await autoBlacklistVideoIfNeeded(video, user, t)
// Set tags to the video
if (tags) {
}
)
+staticRouter.use('/.well-known/host-meta',
+ (_, res: express.Response) => {
+ res.type('application/xml')
+
+ const xml = '<?xml version="1.0" encoding="UTF-8"?>\n' +
+ '<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">\n' +
+ ` <Link rel="lrdd" type="application/xrd+xml" template="${WEBSERVER.URL}/.well-known/webfinger?resource={uri}"/>\n` +
+ '</XRD>'
+
+ res.send(xml).end()
+ }
+)
+
// ---------------------------------------------------------------------------
export {
import { orderBy } from 'lodash'
import 'mocha'
import {
- addVideoToBlacklist, cleanupTests,
+ addVideoToBlacklist,
+ cleanupTests,
createUser,
flushAndRunMultipleServers,
- getBlacklistedVideosList,
+ getBlacklistedVideosList, getMyUserInformation,
getMyVideos,
getVideosList,
killallServers,
searchVideo,
ServerInfo,
setAccessTokensToServers,
+ setDefaultVideoChannel,
updateVideo,
updateVideoBlacklist,
uploadVideo,
import { waitJobs } from '../../../../shared/extra-utils/server/jobs'
import { VideoBlacklist, VideoBlacklistType } from '../../../../shared/models/videos'
import { UserAdminFlag } from '../../../../shared/models/users/user-flag.model'
-import { UserRole } from '../../../../shared/models/users'
+import { User, UserRole, UserUpdateMe } from '../../../../shared/models/users'
+import { getMagnetURI, getYoutubeVideoUrl, importVideo } from '../../../../shared/extra-utils/videos/video-imports'
const expect = chai.expect
describe('When auto blacklist videos', function () {
let userWithoutFlag: string
let userWithFlag: string
+ let channelOfUserWithoutFlag: number
before(async function () {
this.timeout(20000)
})
userWithoutFlag = await userLogin(servers[0], user)
+
+ const res = await getMyUserInformation(servers[0].url, userWithoutFlag)
+ const body: User = res.body
+ channelOfUserWithoutFlag = body.videoChannels[0].id
}
{
await waitJobs(servers)
})
- it('Should auto blacklist a video', async function () {
+ it('Should auto blacklist a video on upload', async function () {
await uploadVideo(servers[0].url, userWithoutFlag, { name: 'blacklisted' })
const res = await getBlacklistedVideosList({
expect(res.body.data[0].video.name).to.equal('blacklisted')
})
- it('Should not auto blacklist a video', async function () {
+ it('Should auto blacklist a video on URL import', async function () {
+ const attributes = {
+ targetUrl: getYoutubeVideoUrl(),
+ name: 'URL import',
+ channelId: channelOfUserWithoutFlag
+ }
+ await importVideo(servers[ 0 ].url, userWithoutFlag, attributes)
+
+ const res = await getBlacklistedVideosList({
+ url: servers[ 0 ].url,
+ token: servers[ 0 ].accessToken,
+ sort: 'createdAt',
+ type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
+ })
+
+ expect(res.body.total).to.equal(2)
+ expect(res.body.data[1].video.name).to.equal('URL import')
+ })
+
+ it('Should auto blacklist a video on torrent import', async function () {
+ const attributes = {
+ magnetUri: getMagnetURI(),
+ name: 'Torrent import',
+ channelId: channelOfUserWithoutFlag
+ }
+ await importVideo(servers[ 0 ].url, userWithoutFlag, attributes)
+
+ const res = await getBlacklistedVideosList({
+ url: servers[ 0 ].url,
+ token: servers[ 0 ].accessToken,
+ sort: 'createdAt',
+ type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
+ })
+
+ expect(res.body.total).to.equal(3)
+ expect(res.body.data[2].video.name).to.equal('Torrent import')
+ })
+
+ it('Should not auto blacklist a video on upload if the user has the bypass blacklist flag', async function () {
await uploadVideo(servers[0].url, userWithFlag, { name: 'not blacklisted' })
const res = await getBlacklistedVideosList({
type: VideoBlacklistType.AUTO_BEFORE_PUBLISHED
})
- expect(res.body.total).to.equal(1)
+ expect(res.body.total).to.equal(3)
})
})