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

Feature/text annotator menu #139

Open
wants to merge 14 commits into
base: develop
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated to Angular 13

### Added
- Text annotator component visualization
- Text/images connection in page change
- Support for styleDefDecl as default style of renditional information
- Apparatus entry inline visualization
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"angular-gridster2": "^13.2.0",
"bootstrap": "^5.1.3",
"dexie": "^3.2.1",
"evt-text-annotator": "^1.1.1",
"jquery": "^3.6.0",
"ng-dynamic-component": "~10.1.0",
"ng2-handy-syntax-highlighter": "^1.0.12",
Expand Down
3 changes: 2 additions & 1 deletion src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
</span>
<evt-nav-bar [ngClass]="{opened: navbarOpened$ | async}" *ngIf="hasNavBar"></evt-nav-bar>
</ng-container>
<ngx-spinner #mainSpinner type="ball-spin-clockwise" bdColor="rgba(51,51,51,0.8)"></ngx-spinner>
<evt-text-annotator></evt-text-annotator>
<ngx-spinner #mainSpinner type="ball-spin-clockwise" bdColor="rgba(51,51,51,0.8)"></ngx-spinner>
10 changes: 10 additions & 0 deletions src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,18 @@ export interface EditionConfig {
defaultImageZoomLevel: number;
showSubstitutionMarker: boolean;
multiPageEngineForCriticalEdition: boolean;
annotatorColors: AnnotatorColors;
annotationTextType: AnnotationTextType;
}

export interface AnnotatorColors {
note: string;
highlights: string[];
}

export type AnnotationTextType = 'annotate' | 'highlight';


export type EditionImagesSources = 'manifest' | 'graphics';

export interface FileConfig {
Expand Down
6 changes: 6 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ import { SubstitutionComponent } from './components/substitution/substitution.co
import { SuppliedComponent } from './components/supplied/supplied.component';
import { SurplusComponent } from './components/surplus/surplus.component';
import { TagsDeclComponent } from './components/tags-decl/tags-decl.component';
import { TextAnnotatorComponent } from './components/annotator/text-annotator/text-annotator.component';
import { TextComponent } from './components/text/text.component';
import { TextPanelComponent } from './panels/text-panel/text-panel.component';
import { TextSourcesComponent } from './view-modes/text-sources/text-sources.component';
Expand Down Expand Up @@ -269,6 +270,11 @@ const DynamicComponents = [
SourcesComponent,
SourcesPanelComponent,
StartsWithPipe,
SuppliedComponent,
SurplusComponent,
TagsDeclComponent,
TextAnnotatorComponent,
TextComponent,
StyledBiblioEntryComponent,
SubstitutionComponent,
TextPanelComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<div class="evt-adder-annotation" [ngStyle]="{'left.px': annotator.options.position.x, 'top.px':annotator.options.position.y}">
<div class="evt-adder-toolbar" *ngIf="annotator.options.showAdder">
<div class="evt-annotator-option evt-annotate" (click)="openCreation('annotate')">
<span>{{'annotate' | translate}} <evt-icon [iconInfo] = "{icon:'annotate', iconSet:'evt'}"></evt-icon></span>
</div>
<div class="evt-annotator-option evt-highlight" (click)="openCreation('highlight')">
<span>{{'highlight' | translate}} <evt-icon [iconInfo] = "{icon:'highlight', iconSet:'evt'}"></evt-icon></span>
</div>
<ng-container *ngIf="annotator.values.type === 'highlight' then createHighlight"></ng-container>
</div>
<ng-container *ngIf="annotator.values.type === 'annotate' then createAnnotation"></ng-container>
</div>

<ng-template #createHighlight>
<div class="evt-annotator-option evt-highlight-colors" *ngFor="let color of annotator.options.highlightColors.highlights">
<div class="evt-highlighter" [ngStyle]="{'background-color': color}"></div>
</div>
</ng-template>

<ng-template #createAnnotation>
<div class="evt-annotate-creator">
<div class="evt-note evt-note-header">
<span><evt-icon [iconInfo] = "{icon:'note', iconSet:'evt'}"></evt-icon> {{'annotatorNote' | translate}}</span>
<evt-icon [iconInfo]="{icon:'close', iconSet:'evt'}" [ngStyle]="{'float': 'right', 'cursor': 'pointer'}" (click)="closeAdder()"></evt-icon>
</div>
<div class="evt-note evt-note-body">
<div class="note-title" attr.contenteditable="{{annotator.options.updateMode}}" attr.data-placeholder="{{'noteTitle' | translate}}"></div>
<div class="note-body" attr.contenteditable="{{annotator.options.updateMode}}" attr.data-placeholder="{{'noteBody' | translate}}"></div>
</div>
<div class="evt-note evt-note-footer" [ngStyle]="{'float': 'right'}">
<evt-button class="btn-anno" label="{{'noteCancel' | translate}}" additionalClasses="btn-annotator"></evt-button>
<evt-button class="btn-anno" label="{{'noteSave' | translate}}" additionalClasses="btn-annotator-light"></evt-button>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
@import "../../../../assets/scss/colors";


$buttonColor: get-anno-color(buttonColors);
$noteColor: get-anno-color(noteColor);


.evt-adder-annotation {
font-family: Junicode, Times, serif;
display: block;
position: absolute;
z-index: 999;
height: auto;
border-radius: 5px;
}

.evt-annotate {
border-right: 1px solid #ccc;
}

.evt-annotator-option {
background: $buttonColor;
padding: 8px 5px;
cursor: pointer;
}

.evt-annotator-option span {
margin: 0;
}

.evt-adder-toolbar {
all: initial;
z-index: 1;
display: flex;
flex-direction: row;
margin-top: 15px;
box-shadow: 0px 0px 9px 0 rgb(0 0 0 / 33%);
border-radius: 5px;
border: 1px solid #ccc;
}

.evt-adder-toolbar::after {
content: "";
position: absolute;
width: 0;
height: 0;
margin-left: -0.5em;
bottom: 25px;
left: 15%;
box-sizing: border-box;
border: 5px solid #ccc;
border-color: transparent transparent #fff #fff;
transform-origin: 0 0;
transform: rotate(135deg);
box-shadow: -3px 3px 3px 0 rgb(0 0 0 / 14%);
}

.evt-highlight-colors div {
width: 20px;
height: 20px;
float: left;
}


.evt-annotate-creator {
width: 280px;
height: auto;
}

[contentEditable=true]:empty:not(:focus):before{
content:attr(data-placeholder);
color:grey;
font-style:italic;
}

.evt-annotate-creator {
margin-top: 15px;
background: $buttonColor;
overflow: hidden;
box-shadow: 0px 0px 9px 0 rgb(0 0 0 / 33%);
}

.evt-annotate-creator::after {
content: "";
position: absolute;
width: 0;
height: 0;
margin-left: -0.5em;
bottom: 92%;
left: 15%;
box-sizing: border-box;
border: 5px solid #ccc;
border-color: transparent transparent #E4EBF6 #E4EBF6;
transform-origin: 0 0;
transform: rotate(135deg);
box-shadow: -3px 3px 3px 0 rgb(0 0 0 / 14%);
}

.evt-note-header {
background-color: $noteColor;
padding: 10px;
}

.evt-note.evt-note-body {
padding: 20px;
}

.note-title,
.note-body {
border: 1px solid #ccc;
padding: 5px;
margin-top: 10px;
}

.note-title:focus,
.note-body:focus {
outline: none;
border: 1px solid #000;
}

.note-body {
height: 100px;
}

.evt-note-footer {
padding: 0 20px 20px 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { TextAnnotatorComponent } from './text-annotator.component';

describe('TextAnnotatorComponent', () => {
let component: TextAnnotatorComponent;
let fixture: ComponentFixture<TextAnnotatorComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TextAnnotatorComponent ],
})
.compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(TextAnnotatorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { AnnotationTextType, AnnotatorColors, AppConfig } from 'src/app/app.config';
import { AnnotatorService } from 'src/app/services/annotator/annotator.service';

interface TextAnnotation {
options: {
position: AnnotatorPosition;
highlightColors: AnnotatorColors;
showAdder: Boolean;
updateMode: Boolean;
}
values: {
range: Range;
type: AnnotationTextType;
selectedText: string;
}
}
interface AnnotatorPosition {
x: number;
y: number;
}
@Component({
selector: 'evt-text-annotator',
templateUrl: './text-annotator.component.html',
styleUrls: ['./text-annotator.component.scss'],
})
export class TextAnnotatorComponent implements OnDestroy {
private subscriptions: Subscription[] = [];
public annotator: TextAnnotation = {
options: {
position: { x: 0, y: 0 },
highlightColors: AppConfig.evtSettings.edition.annotatorColors,
showAdder: false,
updateMode: true,
},
values: {
range: null,
type: null,
selectedText: '',
},
}

constructor(
private annotatorService: AnnotatorService,
) {
const { values } = this.annotator;

this.subscriptions.push(this.annotatorService.textSelection$
.subscribe((selection) => {
values.selectedText = selection.toString();
if (/\S/.test(values.selectedText)) {
this.openAdder(selection);
} else {
this.closeAdder();
}
}));
}

openAdder(selection: Selection) {
const { options, values } = this.annotator;
values.range = selection.getRangeAt(0);
options.showAdder = true
const rect = values.range.getBoundingClientRect();
options.position = { y: rect.bottom, x: rect.left };
}

closeAdder() {
const { options, values } = this.annotator;
options.showAdder = false;
values.type = null;
}

openCreation(choice: string) {
const { options, values } = this.annotator;
values.type = choice as AnnotationTextType;
options.showAdder = choice !== 'annotate';
}

ngOnDestroy() {
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
}
}
18 changes: 18 additions & 0 deletions src/app/ui-components/button/button.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,22 @@
width: 40px;
}
}
&.btn-annotator {
@include themify($themes) {
color: themed("toolsColor");
background-color: themed("toolsBackgroundDarker");
border-color: themed("toolsBackgroundDarker");
width: 80px;
margin-left: 10px;
}
}
&.btn-annotator-light {
@include themify($themes) {
color: themed("toolsColor");
background-color: themed("annotatorColor");
border-color: themed("annotatorColor");
width: 80px;
margin-left: 10px;
}
}
}
Loading