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

Fix file issues #7257

Merged
merged 5 commits into from
Oct 30, 2023
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
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<ng-template #template>
<div *ngIf="!question.isReadOnly" role="button" tabindex="0" [class]="question.getChooseFileCss()"
<label tabindex="0" [class]="question.getChooseFileCss()"
[attr.for]="question.inputId" [attr.aria-label]="question.chooseButtonText" [key2click]>
<svg *ngIf="question.cssClasses.chooseFileIconId" [title]="question.chooseButtonText"
[iconName]="question.cssClasses.chooseFileIconId" [size]="'auto'" sv-ng-svg-icon></svg>
<span>{{ question.chooseButtonText }}</span>
</div>
</label>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
val.name
}}</a>
</div>
<div [class]="question.cssClasses.imageWrapper">
<div [class]="question.getImageWrapperCss(val)">
<img *ngIf="question.canPreviewImage(val)" [attr.src]="val.content | safeUrl"
[style.height]="question.imageHeight" [style.width]="question.imageWidth" alt="File preview" />
<svg *ngIf="question.defaultImage(val)" [iconName]="question.cssClasses.defaultImageIconId"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
<template>
<div
v-if="!question.isReadOnly"
role="button"
<label
tabindex="0"
:class="question.getChooseFileCss()"
:for="question.inputId"
Expand All @@ -15,7 +13,7 @@
:size="'auto'"
></sv-svg-icon>
<span>{{ question.chooseButtonText }}</span>
</div>
</label>
</template>
<script setup lang="ts">
import type { QuestionFileModel, Action } from "survey-core";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
>{{ val.name }}</a
>
</div>
<div :class="question.cssClasses.imageWrapper">
<div :class="question.getImageWrapperCss(val)">
<img
v-if="question.canPreviewImage(val)"
:src="val.content"
Expand Down
4 changes: 4 additions & 0 deletions src/actions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface IAction {
* @see visible
*/
enabled?: boolean;
enabledIf?: () => boolean;
/**
* Specifies the visibility of the action item's title.
* @see title
Expand Down Expand Up @@ -441,10 +442,13 @@ export class Action extends BaseAction implements IAction, ILocalizableOwner {
public getVisible(): boolean {
return this._visible;
}

public enabledIf?: () => boolean;
public setEnabled(val: boolean): void {
this._enabled = val;
}
public getEnabled(): boolean {
if(this.enabledIf) return this.enabledIf();
return this._enabled;
}
public setComponent(val: string): void {
Expand Down
1 change: 1 addition & 0 deletions src/defaultCss/defaultV2Css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ export var defaultV2Css = {
removeFileButton: "sd-context-btn--negative sd-file__remove-file-button",
dragAreaPlaceholder: "sd-file__drag-area-placeholder",
imageWrapper: "sd-file__image-wrapper",
imageWrapperDefaultImage: "sd-file__image-wrapper--default-image",
single: "sd-file--single",
singleImage: "sd-file--single-image",
mobile: "sd-file--mobile",
Expand Down
4 changes: 4 additions & 0 deletions src/defaultV2-theme/blocks/sd-action.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ svg.sd-action--icon {
cursor: default;
opacity: 0.25;
pointer-events: none;

use {
fill: $font-questiondescription-color;
}
}

.sd-action:not(.sd-action--pressed):hover,
Expand Down
38 changes: 27 additions & 11 deletions src/defaultV2-theme/blocks/sd-file.scss
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,10 @@
.sd-file__preview {
position: relative;
display: flex;
align-items: center;
align-items: stretch;
flex-direction: column;
min-height: 100%;
width: calcSize(12);
margin: 0;

.sd-file__default-image {
Expand Down Expand Up @@ -182,6 +183,8 @@
white-space: normal;
word-break: break-all;
width: calcSize(12);
min-width: 100%;
max-width: 100%;
overflow: hidden;
max-height: calcSize(6);
text-overflow: ellipsis;
Expand All @@ -203,30 +206,34 @@
.sd-file__image-wrapper {
position: relative;
text-align: center;
min-width: calcSize(12);
display: flex;
align-items: center;
justify-content: center;
width: calcSize(12);
min-height: calcSize(12);
height: calcSize(12);
background: $background-dim;

img:not(.sd-file__default-image) {
display: block;
max-width: 100%;
max-height: 100%;
width: calcSize(12);
height: calcSize(12);
object-fit: contain;
background: $background-dim;
}
}

.sd-file__image-wrapper--default-image {
background: transparent;
}

.sd-file--single {
img:hover+.sd-file__remove-file-button {
display: none;
}
}

.sd-file--mobile:first-child {
.sd-file__list {
height: calc(100% - 4 * #{$base-unit});
}
}

.sd-file--single-image {
height: calc(36 * #{$base-unit});

Expand All @@ -244,14 +251,17 @@
width: 100%;
}

.sd-file__image-wrapper {
background-color: $background-dim-light;
}

.sd-file__image-wrapper {
min-height: 100%;
min-width: 100%;

img {
width: 100%;
height: 100%;
background-color: $background-dim-light;
}
}

Expand All @@ -264,12 +274,18 @@
a {
color: transparent;
width: 100%;
min-width: 100%;
max-width: 100%;
height: 100%;
outline: none;
}
}
}

.sd-file__image-wrapper.sd-file__image-wrapper--default-image {
background: transparent;
}

.sd-file>input:focus+.sd-file__decorator .sd-file__choose-btn {
&.sd-file__choose-btn--icon {
use {
Expand Down Expand Up @@ -326,7 +342,7 @@
}

.sd-file__video-container {
background-color: $background-dim;
background-color: $background-dark;
position: absolute;
top: 0;
left: 0;
Expand Down
4 changes: 2 additions & 2 deletions src/knockout/components/file/choose-file.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div tabindex="0" role="button" data-bind="css: question.koChooseFileCss, key2click, attr: { for: question.inputId, 'aria-label': question.koGetChooseButtonText() }">
<label tabindex="0" data-bind="css: question.koChooseFileCss, key2click, attr: { for: question.inputId, 'aria-label': question.koGetChooseButtonText() }">
<!-- ko if: question.cssClasses.chooseFileIconId -->
<!-- ko component: { name: 'sv-svg-icon', params: { title: question.koGetChooseButtonText(), iconName: question.cssClasses.chooseFileIconId, size: 'auto' } } --><!-- /ko -->
<!-- /ko -->
<span data-bind="text: question.koGetChooseButtonText()"></span>
</div>
</label>
2 changes: 1 addition & 1 deletion src/knockout/components/file/file-preview.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div data-bind="css: question.cssClasses.fileList, foreach: question.koData, visible: question.koHasValue">
<span data-bind="visible: question.isPreviewVisible($index()), css: question.cssClasses.preview">
<!-- ko template: { name: 'survey-question-file-sign', data: {question: question, item: $data, fileSignCss: question.cssClasses.fileSign} } --><!-- /ko -->
<div data-bind="css: question.cssClasses.imageWrapper">
<div data-bind="css: question.getImageWrapperCss($data)">
<!-- ko if: question.canPreviewImage($data) -->
<img data-bind="attr: { src: $data.content }, style : { height: question.imageHeight, width: question.imageWidth }" alt="File preview">
<!-- /ko -->
Expand Down
26 changes: 16 additions & 10 deletions src/question_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Helpers } from "./helpers";
import { Camera } from "./utils/camera";
import { LocalizableString } from "./localizablestring";
import { settings } from "./settings";
import { getRenderedSize } from "./utils/utils";

/**
* A class that describes the File Upload question type.
Expand Down Expand Up @@ -92,8 +93,7 @@ export class QuestionFileModel extends Question {
const isUploading = this.isUploading;
const isPlayingVideo = this.isPlayingVideo;
const isDefaultV2Theme = this.isDefaultV2Theme;
const isReadOnly = this.isInputReadOnly;
return !isUploading && !isPlayingVideo && !isReadOnly && isDefaultV2Theme;
return !isUploading && !isPlayingVideo && isDefaultV2Theme;
}

constructor(name: string) {
Expand Down Expand Up @@ -162,6 +162,7 @@ export class QuestionFileModel extends Question {
iconSize: "auto",
title: <string>(new ComputedUpdater<string>(() => this.takePhotoCaption) as any),
showTitle: <boolean>(new ComputedUpdater<boolean>(() => !this.isAnswered) as any),
enabledIf: () => !this.isInputReadOnly,
action: () => {
this.startVideo();
}
Expand All @@ -172,6 +173,7 @@ export class QuestionFileModel extends Question {
iconSize: "auto",
title: <string>(new ComputedUpdater<string>(() => this.clearButtonCaption) as any),
showTitle: false,
enabledIf: () => !this.isInputReadOnly,
innerCss: <string>(new ComputedUpdater<string>(() => this.cssClasses.removeButton) as any),
action: () => {
this.doClean();
Expand All @@ -180,10 +182,9 @@ export class QuestionFileModel extends Question {
[this.closeCameraAction, this.changeCameraAction, this.takePictureAction].forEach((action) => {
action.cssClasses = {};
});
this.registerFunctionOnPropertiesValueChanged(["currentMode", "isAnswered"], () => {
this.updateActions();
this.registerFunctionOnPropertiesValueChanged(["sourceType", "currentMode", "isAnswered"], () => {
this.updateActionsVisibility();
});
this.updateActions();
this.actionsContainer.actions = [this.chooseFileAction, this.startCameraAction, this.cleanAction];
this.fileNavigator.actions = [this.prevFileAction, this.fileIndexAction, this.nextFileAction];
}
Expand All @@ -198,13 +199,14 @@ export class QuestionFileModel extends Question {
this.startVideoInCamera();
}, 0);
}

private startVideoInCamera(): void {
this.camera.startVideo(this.videoId, (stream: MediaStream) => {
this.videoStream = stream;
if(!stream) {
this.stopVideo();
}
}, this.imageWidth, this.imageHeight);
}, getRenderedSize(this.imageWidth), getRenderedSize(this.imageHeight));
}
public stopVideo(): void {
this.setIsPlayingVideo(false);
Expand Down Expand Up @@ -480,9 +482,10 @@ export class QuestionFileModel extends Question {
}
}
}
private updateActions() {
this.chooseFileAction.visible = this.hasFileUI;
this.startCameraAction.visible = this.hasVideoUI;
private updateActionsVisibility() {
const isDesignMode = this.isDesignMode;
this.chooseFileAction.visible = (!isDesignMode && this.hasFileUI) || (isDesignMode && this.sourceType !== "camera");
this.startCameraAction.visible = (!isDesignMode && this.hasVideoUI) || (isDesignMode && this.sourceType !== "file");
this.cleanAction.visible = !!this.isAnswered;
}
get inputTitle(): string {
Expand Down Expand Up @@ -778,6 +781,9 @@ export class QuestionFileModel extends Question {
}
return questionPlainData;
}
public getImageWrapperCss(data: any): string {
return new CssClassBuilder().append(this.cssClasses.imageWrapper).append(this.cssClasses.imageWrapperDefaultImage, this.defaultImage(data)).toString();
}
protected getActionsContainerCss(css: any): string {
return new CssClassBuilder()
.append(css.actionsContainer)
Expand Down Expand Up @@ -862,7 +868,7 @@ export class QuestionFileModel extends Question {
endLoadingFromJson(): void {
super.endLoadingFromJson();
this.updateCurrentMode();
this.updateActions();
this.updateActionsVisibility();
this.loadPreview(this.value);
}
protected needResponsiveness(): boolean {
Expand Down
5 changes: 2 additions & 3 deletions src/react/components/file/file-choose-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@ export class SurveyFileChooseButton extends ReactSurveyElement {
}
render() {
return attachKey2click(
<div
role="button"
<label
tabIndex={0}
className={this.question.getChooseFileCss()}
// htmlFor={this.question.inputId}
aria-label={this.question.chooseButtonText}
>
{(!!this.question.cssClasses.chooseFileIconId) ? <SvgIcon title={this.question.chooseButtonText} iconName={this.question.cssClasses.chooseFileIconId} size={"auto"}></SvgIcon>: null }
<span>{this.question.chooseButtonText}</span>
</div>
</label>
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/react/components/file/file-preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class SurveyFilePreview extends SurveyElementBase<{ question: QuestionFil
style={{ display: this.question.isPreviewVisible(index) ? undefined : "none" }}
>
{this.renderFileSign(this.question.cssClasses.fileSign, val)}
<div className={this.question.cssClasses.imageWrapper}>
<div className={this.question.getImageWrapperCss(val)}>
{this.question.canPreviewImage(val) ? (
<img
src={val.content}
Expand Down
Loading