diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 23dc2b3..c1be042 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,6 +31,7 @@ jobs: run: npm run build --prod -- --base-href /playground/ deploy: + if: github.event_name == 'push' || github.event_name == 'release' runs-on: ubuntu-latest steps: - name: Checkout code diff --git a/public/templates/algorithms/sorting.sqz b/public/templates/algorithms/sorting.sqz index 19891bf..2fd40f1 100644 --- a/public/templates/algorithms/sorting.sqz +++ b/public/templates/algorithms/sorting.sqz @@ -13,7 +13,7 @@ fn quick_sort(arr) { for (var i = 0; i < arr.length; i++) { if (arr[i] < pivot) { left.push(arr[i]); - } else if (arr[i] > pivot) { + } elif (arr[i] > pivot) { right.push(arr[i]); } else { equal.push(arr[i]); @@ -25,5 +25,5 @@ fn quick_sort(arr) { var arr = [38, 27, 43, 3, 9, 82, 10]; -log("Unsorted array:", arr); -log("Sorted array:", quick_sort(arr)); +log("Unsorted array:" + arr); +log("Sorted array:" + quick_sort(arr)); \ No newline at end of file diff --git a/public/templates/basic/data-structures.sqz b/public/templates/basic/data-structures.sqz index 3872b49..6277ede 100644 --- a/public/templates/basic/data-structures.sqz +++ b/public/templates/basic/data-structures.sqz @@ -1,19 +1,24 @@ // The basic data structures in sQeeZ var intValue = 42; -log("Integer value:", intValue); +log("Integer value:" + intValue); var doubleValue = 3.14159; -log("Double value:", doubleValue); +log("Double value:" + doubleValue); var charValue = 'A'; -log("Character value:", charValue); +log("Character value:" + charValue); var stringValue = "Hello, World!"; -log("String value:", stringValue); +log("String value:" + stringValue); + +var boolValue = false; + +const constant = "I am immutable!"; +log(constant); var array = [1, 2, 3, 4, 5]; -log("Array: ", array); +log("Array: " + array); var object = { name: "John Doe", @@ -21,4 +26,4 @@ var object = { isEmployed: true }; -log("Object: ", person); \ No newline at end of file +log("Object: " + person); \ No newline at end of file diff --git a/public/templates/basic/hello-world.sqz b/public/templates/basic/hello-world.sqz index 59ed93b..c075881 100644 --- a/public/templates/basic/hello-world.sqz +++ b/public/templates/basic/hello-world.sqz @@ -1,2 +1,13 @@ // This is a simple "Hello World" program in sQeeZ + +// Basic log message log("Hello, World!"); + +// Warning message +warn("This is a warning message!"); + +// Error message +error("This is an error message!"); + +// Colored log message +logc("Custom colored message!", #7F00FF); \ No newline at end of file diff --git a/public/templates/overview.json b/public/templates/overview.json index ca9d21b..116119f 100644 --- a/public/templates/overview.json +++ b/public/templates/overview.json @@ -20,6 +20,15 @@ "name": "Data Structures", "code": "./templates/basic/data-structures.sqz" }] + }, { + "name": "Short Notation", + "templates": [{ + "name": "Arrays", + "code": "./templates/short-notation/arrays.sqz" + }, { + "name": "Objects", + "code": "./templates/short-notation/objects.sqz" + }] }, { "name": "Algorithms", "templates": [{ @@ -29,11 +38,5 @@ "name": "Fibonacci", "code": "./templates/algorithms/fibonacci.sqz" }] - }, { - "name": "Short Notation", - "templates": [{ - "name": "Arrays", - "code": "./templates/short-notation/arrays.sqz" - }] }] } \ No newline at end of file diff --git a/public/templates/short-notation/arrays.sqz b/public/templates/short-notation/arrays.sqz index 2dbc3b2..e83a92d 100644 --- a/public/templates/short-notation/arrays.sqz +++ b/public/templates/short-notation/arrays.sqz @@ -1,2 +1,14 @@ // Short notation of array functionalities in sQeeZ -@1 2 3 4 5 |> map(*2) |> filter(>10) \ No newline at end of file + +// Adds 3 to each: [8, 13, 18, 23, 28] +// Filters > 15: [18, 23, 28] +// Reduces by summing with initial value 0: 69 + 0 = 69 +@5,10,15,20,25 |> MAP(+3) |> FILTER(>15) |> REDUCE(+0); + +// Concatenates [1, 2] with [3, 4]: [1, 2, 3, 4] +// Zips with ['a', 'b', 'c', 'd']: [(1, 'a'), (2, 'b'), (3, 'c'), (4, 'd')] +@1,2 |> CONCAT(@3,4) |> ZIP(@'a','b','c','d'); + +// Filters < 350: [100, 200, 300] +// counts: 3 +COUNT((@100,200,300,400 |> FILTER(<350))); diff --git a/public/templates/short-notation/objects.sqz b/public/templates/short-notation/objects.sqz new file mode 100644 index 0000000..e964746 --- /dev/null +++ b/public/templates/short-notation/objects.sqz @@ -0,0 +1,8 @@ +// Short notation of object functionalities in sQeeZ + +// { +// a: 1, +// b: false, +// c: "last value" +// } +@a:1,b:false,c:"last value"; \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html index 3436d31..b89d9b8 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,14 +1,57 @@ -
- -
- @if (screenWidth >= 992) { - +
+ + +
+ + + +
+
+ + +

Templates

+ + @for (section of categories; track section) { + + } + +
+ +
+ + +
+
+
+
+ + + + + + + + + + @for(subSection of section.templates; track subSection) { + + + } - - -
-
\ No newline at end of file + + \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss index c8c1fb1..d742d15 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,13 +1,112 @@ -%full-size { - width: 100%; - height: 100%; +.app-container { + display: flex; + flex-direction: column; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.is-mobile .toolbar { + position: fixed; + z-index: 2; } -.app-container { +.sidenav-container { + flex: 1; +} + +.is-mobile .sidenav-container { + flex: 1 0 auto; +} + +.toolbar { + display: flex; + justify-content: space-between; + height: 4rem; + background-color: var(--toolbar); + color: var(--font-color); + border-bottom: 0.5px solid var(--border); +} + +.menu, +.actions { + display: flex; + align-items: center; + height: 100%; + gap: 0.5rem; + + .logo { + height: 75%; + width: auto; + border-radius: 5px; + } +} + +.language-trigger .fi { + width: 24px; + transform: translateY(-4px); +} + +.language-select .fi { + width: 24px; + transform: translateY(-2px); +} +.heading { + text-align: center; + text-decoration: underline; +} + +mat-sidenav { + background-color: var(--sidenav); + color: var(--font-color); + border-radius: 0; +} + +.sidenav-content { + display: flex; + flex-direction: column; + overflow: hidden; + height: 100%; + width: 100%; + background-color: var(--content); +} + +router-outlet { display: flex; flex-direction: column; justify-content: flex-start; - @extend %full-size; +} + +.controls { + display: flex; + justify-content: space-between; + position: fixed; + height: 3rem; + width: 100%; + bottom: 0; + + button { + height: 100%; + width: 50%; + border-radius: 0; + } +} + +mat-expansion-panel { + background-color: transparent; + box-shadow: none; +} + +.content-item { + width: 100%; +} + +.table-of-contents { + display: flex; + flex-direction: column; + gap: 1rem; } .core { @@ -16,19 +115,19 @@ justify-content: flex-start; } -app-code { - flex: 1; -} +:host-context(.light-theme) { + --mat-expansion-header-indicator-color: var(--font-color); -.dark-theme { - .core { - background-color: #222222; + button { + color: var(--font-color); } -} -.light-theme { - .core { - background-color: #f5f5f5; + button:hover { + background-color: rgba(255, 171, 242, 0.75) !important; + } + + .controls button { + background-color: var(--toolbar); } } diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 22a7556..57c5e5b 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,10 +1,13 @@ import { TestBed } from '@angular/core/testing'; import { AppComponent } from './app.component'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; describe('AppComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AppComponent], + imports: [AppComponent, HttpClientTestingModule, BrowserAnimationsModule], + }).compileComponents(); spyOnProperty(window, 'innerWidth').and.returnValue(0); spyOnProperty(window, 'innerHeight').and.returnValue(0); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index a0ba87a..4ab5ed0 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,29 +1,91 @@ -import { AfterViewInit, Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; -import { ToolbarComponent } from './components/toolbar/toolbar.component'; -import { TemplatesComponent } from './components/templates/templates.component'; +import { ChangeDetectorRef, Component, Inject, inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core'; +import { DataService } from './services/data.service'; +import { SyncService } from './services/sync.service'; +import { CommonModule, isPlatformBrowser } from '@angular/common'; +import { MatButtonModule } from '@angular/material/button'; +import { MatExpansionPanel, MatExpansionPanelTitle, MatExpansionPanelHeader } from '@angular/material/expansion'; +import { MatIconModule } from '@angular/material/icon'; +import { MatListModule } from '@angular/material/list'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatToolbarModule } from '@angular/material/toolbar'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { TemplateCategory } from './interfaces/template-category.interface'; +import { MediaMatcher } from '@angular/cdk/layout'; +import { SnackbarService } from './services/snackbar.service'; +import { MatDialog } from '@angular/material/dialog'; +import { SettingsComponent } from './components/settings/settings.component'; +import { lastValueFrom } from 'rxjs'; +import { Template } from './interfaces/template.interface'; import { CodeComponent } from './components/code/code.component'; import { ConsoleComponent } from './components/console/console.component'; -import { ScreenDirective } from './directives/screen.directive'; @Component({ selector: 'app-root', standalone: true, - imports: [RouterOutlet, ToolbarComponent, TemplatesComponent, CodeComponent, ConsoleComponent, ScreenDirective], - providers: [ScreenDirective], + imports: [CommonModule, MatToolbarModule, MatButtonModule, MatIconModule, MatSidenavModule, MatListModule, MatTooltipModule, MatMenuModule, MatExpansionPanel, MatExpansionPanelTitle, MatExpansionPanelHeader, CodeComponent, ConsoleComponent], templateUrl: './app.component.html', styleUrl: './app.component.scss' }) -export class AppComponent implements AfterViewInit { +export class AppComponent implements OnInit, OnDestroy { title = 'playground'; - public screenWidth: number = 0; - public screenHeight: number = 0; + public mobileQuery!: MediaQueryList; + public currentTheme: string = 'dark'; + categories: TemplateCategory[] = []; + + private _mobileQueryListener: () => void; - ngAfterViewInit(): void { - try { - this.screenWidth = window.innerWidth; - this.screenHeight = window.innerHeight; - } catch (err) { } + constructor( + @Inject(PLATFORM_ID) private platformId: any, + private dataService: DataService, + private syncService: SyncService, + private snackBar: SnackbarService, + private dialog: MatDialog, + ) { + const changeDetectorRef = inject(ChangeDetectorRef); + const media = inject(MediaMatcher); + + this.mobileQuery = media.matchMedia('(max-width: 600px)'); + this._mobileQueryListener = () => changeDetectorRef.detectChanges(); + this.mobileQuery.addListener(this._mobileQueryListener); + } + + ngOnInit(): void { + this.currentTheme = this.getSystemTheme(); + this.setTheme(); + this.categories = this.dataService.templates; + } + + ngOnDestroy(): void { + this.mobileQuery.removeListener(this._mobileQueryListener); + } + + toggleTheme(): void { + this.currentTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; + this.syncService.setTheme(this.currentTheme); + this.setTheme(); + } + + openDocumentation(): void { + window.location.href = 'https://sqeez-scripting-language.github.io/documentation/'; + } + + openSettings(): void { + this.dialog.open(SettingsComponent); + } + + async showCode(template: Template) { + this.syncService.setCode(await lastValueFrom(this.dataService.getTemplateCode(template.code))); + } + + private getSystemTheme(): string { + return (typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; + } + + private setTheme(): void { + if (isPlatformBrowser(this.platformId)) { + document.body.classList.toggle('dark-theme', this.currentTheme === 'dark'); + document.body.classList.toggle('light-theme', this.currentTheme === 'light'); + } } - } diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 14da742..71f59eb 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -3,8 +3,8 @@ import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; -import { provideHttpClient, withFetch } from '@angular/common/http'; +import { provideHttpClient } from '@angular/common/http'; export const appConfig: ApplicationConfig = { - providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimationsAsync(), provideHttpClient(withFetch())] + providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimationsAsync(), provideHttpClient()] }; diff --git a/src/app/components/code/code.component.scss b/src/app/components/code/code.component.scss index 5dbf65d..9fc99e8 100644 --- a/src/app/components/code/code.component.scss +++ b/src/app/components/code/code.component.scss @@ -5,6 +5,7 @@ align-items: center; height: 60vh; width: 100vw; + border-right: 0.5px solid var(--border); } .header { @@ -21,12 +22,14 @@ flex-direction: column; justify-content: center; box-sizing: border-box; + color: var(--font-color); } .header { display: flex; align-items: center; gap: 0.25rem; + background-color: var(--code); } p { @@ -39,7 +42,13 @@ p { align-items: center; flex-grow: 1; height: 100%; - border-right: 0; + border: 0.5px solid var(--border); + border-right: 0 !important; + background-color: var(--header); +} + +.control-area > button { + color: var(--font-color); } .editor-container { @@ -50,16 +59,20 @@ p { width: 100%; line-height: 1.5; font-family: 'Courier New', monospace; + border: 0.5px solid var(--border); .line-numbers { - width: 50px; + min-width: 30px; overflow: hidden; white-space: pre; user-select: none; line-height: inherit; - text-align: right; - font-size: var(--font-size); + text-align: center; padding: 10px; + font-size: var(--font-size); + border-right: 0.5px solid var(--border); + color: var(--line-numbers); + background-color: var(--code); } .editor { @@ -78,76 +91,22 @@ p { margin: 0; padding: 10px 10px; } -} - - -:host-context(.dark-theme) { - .code-container { - border-right: 0.5px solid #e6e6e6; - } - - .file { - color: white; - } - - .control-area { - border: 0.5px solid #e6e6e6; - background-color: #181818; - } - - .editor-container { - border: 0.5px solid #e6e6e6; - - textarea { - background-color: #222222; - color: white; - } - } - .line-numbers { - border-right: 0.5px solid #e6e6e6; - background-color: #444444; - color: white; + textarea { + background-color: var(--code); + color: var(--font-color); } } :host-context(.light-theme) { - .code-container { - border-right: 0.5px solid #181818; - } - - .file { - color: black; - } - - .control-area { - border: 0.5px solid #181818; - background-color: #e6e6e6; - } - - .control-area > button { - color: black; - } - - .editor-container { - border: 0.5px solid #181818; - - textarea { - background-color: #f5f5f5; - color: black; - } - } - - .line-numbers { - border-right: 0.5px solid #181818; - background-color: #cccccc; - color: black; + .control-area > button:hover { + background-color: var(--highlight) !important; } } @media (min-width: 992px) { .code-container { height: calc(100vh - 7.5svh - 0.5px); - width: 100%; + width: calc(65vw - 1px); } } \ No newline at end of file diff --git a/src/app/components/code/code.component.ts b/src/app/components/code/code.component.ts index 84f0500..d63e32c 100644 --- a/src/app/components/code/code.component.ts +++ b/src/app/components/code/code.component.ts @@ -73,6 +73,10 @@ export class CodeComponent implements OnInit, OnDestroy { } async copyCode() { + if (this.code === '') { + this.snackbarService.open('No code to copy!'); + return; + } const textarea = document.createElement('textarea'); textarea.value = this.code; textarea.style.position = 'fixed'; diff --git a/src/app/components/console/console.component.scss b/src/app/components/console/console.component.scss index 8113aad..23e61c1 100644 --- a/src/app/components/console/console.component.scss +++ b/src/app/components/console/console.component.scss @@ -14,6 +14,8 @@ height: 5svh; width: calc(100% - 1em); padding-left: 1em; + color: var(--font-color); + background-color: var(--header); div { display: flex; @@ -23,47 +25,30 @@ } } +.header > button { + color: var(--font-color); +} + +:host-context(.light-theme) { + .header > button:hover { + background-color: var(--highlight) !important; + } +} + .terminal { flex: 1; width: 90%; line-height: 1.5; padding: 5%; + border: 0.5px solid var(--border); + color: var(--font-color); font-family: 'Cascadia Code', 'Courier New', Courier, monospace; -} - -:host-context(.dark-theme) { - .header { - color: white; - } - - .terminal { - background-color: #201c1c; - border: 0.5px solid #e6e6e6; - color: white; - } -} - -:host-context(.light-theme) { - .header { - color: black; - background-color: #e6e6e6; - } - - .header > button { - color: black; - } - - .terminal { - background-color: #cccccc; - border: 0.5px solid #181818; - color: black; - } - + background-color: var(--console); } @media (min-width: 992px) { .console-container { height: calc(100vh - 7.5svh - 0.5px); - width: 32vw; + width: 35vw; } } \ No newline at end of file diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html index 58d2367..bfda4e1 100644 --- a/src/app/components/settings/settings.component.html +++ b/src/app/components/settings/settings.component.html @@ -1,7 +1,7 @@

Settings

-
diff --git a/src/app/components/settings/settings.component.scss b/src/app/components/settings/settings.component.scss index ccb60f5..76b391c 100644 --- a/src/app/components/settings/settings.component.scss +++ b/src/app/components/settings/settings.component.scss @@ -1,5 +1,6 @@ .settings-container { overflow: hidden; + background-color: var(--toolbar); } .header { @@ -23,26 +24,24 @@ mat-dialog-actions { justify-content: space-between; } -:host-context(.dark-theme) { - .settings-container { - background-color: #aaaaaa; - } -} - :host-context(.light-theme) { - .settings-container { - background-color: #ffffff + --mdc-dialog-subhead-color: var(--font-color); + --mdc-outlined-text-field-label-text-color: var(--font-color); + --mdc-outlined-text-field-input-text-color: var(--font-color); + --mdc-outlined-text-field-hover-label-text-color: var(--font-color); + --mdc-outlined-text-field-hover-outline-color: var(--font-color); + + .close { + color: var(--font-color); } - --mdc-dialog-subhead-color: black; - --mdc-outlined-text-field-label-text-color: black; - --mdc-outlined-text-field-input-text-color: black; - --mdc-outlined-text-field-hover-label-text-color: black; - --mdc-outlined-text-field-hover-outline-color: black; + .close:hover { + background-color: var(--highlight) !important; + } mat-dialog-actions button { - background-color: #ffffff; - color: #000; + background-color: var(--toolbar); + color: var(--font-color); border-radius: 4px; } @@ -51,26 +50,17 @@ mat-dialog-actions { } mat-dialog-actions button:hover { - background-color: #e0e0e0; - } - - mat-dialog-actions button.mat-raised-button.color-primary { - background-color: #3f51b5; - color: white; - } - - mat-dialog-actions button.mat-raised-button.color-primary:hover { - background-color: #303f9f; + background-color: var(--highlight) !important; } mat-dialog-actions button[disabled] { - background-color: #f0f0f0; + background-color: var(--disabled); color: rgba(0, 0, 0, 0.38); cursor: not-allowed; box-shadow: none; } mat-dialog-actions button[disabled]:hover { - background-color: #f0f0f0; + background-color: var(--disabled); } } diff --git a/src/app/components/templates/templates.component.html b/src/app/components/templates/templates.component.html deleted file mode 100644 index dfe52b3..0000000 --- a/src/app/components/templates/templates.component.html +++ /dev/null @@ -1,40 +0,0 @@ -
-
- @if (!isCollapsed) { -
Templates
- } - @if (screenWidth < 992) { - - } @else { - - } -
- @if (!isCollapsed) { - - @for (category of categories; track category; let i = $index) { - - - {{ category.name }} - -
- @for (template of category.templates; track template) { - - } -
-
- } -
- } -
\ No newline at end of file diff --git a/src/app/components/templates/templates.component.scss b/src/app/components/templates/templates.component.scss deleted file mode 100644 index be14252..0000000 --- a/src/app/components/templates/templates.component.scss +++ /dev/null @@ -1,97 +0,0 @@ -.templates-container { - overflow-y: scroll; -} - -.templates-container.collapsed { - width: fit-content; -} - -.header { - display: flex; - justify-content: space-between; - align-items: center; - height: 5svh; - width: calc(100% - 1em); - padding-left: 1em; - - div { - display: flex; - justify-content: center; - align-items: center; - gap: 0.25rem; - } -} - -.collapsed .header { - width: 100%; - padding-left: 0; -} - -.templates { - width: 100%; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - gap: 0.5em; - - button { - width: 100%; - } -} - -:host-context(.dark-theme) { - .templates-container { - border-right: 0.5px solid #e6e6e6; - } - - .header { - border-bottom: 0.5px solid #e6e6e6; - color: white; - } -} - -:host-context(.light-theme) { - .templates-container { - border-right: 0.5px solid #181818; - background-color: #f5f5f5; - } - - .header { - border-bottom: 0.5px solid #181818; - } - - mat-accordion { - background-color: #f5f5f5; - color: black; - - mat-expansion-panel { - background-color: #e6e6e6; - border: 1px solid #cccccc; - - mat-expansion-panel-header { - background-color: #e6e6e6; - } - - mat-panel-title { - color: black; - } - } - - .templates { - button { - background-color: #e6e6e6; - color: black; - } - } - } - - --mat-expansion-header-indicator-color: black; -} - -@media (min-width: 992px) { - .templates-container { - height: calc(100vh - 7.5svh - 0.5px); - width: calc(18vw - 1px); - } -} \ No newline at end of file diff --git a/src/app/components/templates/templates.component.spec.ts b/src/app/components/templates/templates.component.spec.ts deleted file mode 100644 index c0c1d55..0000000 --- a/src/app/components/templates/templates.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TemplatesComponent } from './templates.component'; -import { HttpClientModule } from '@angular/common/http'; -import { DataService } from '../../services/data.service'; -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -describe('TemplatesComponent', () => { - let component: TemplatesComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [TemplatesComponent, BrowserAnimationsModule, HttpClientModule], - providers: [DataService] - }) - .compileComponents(); - - fixture = TestBed.createComponent(TemplatesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/components/templates/templates.component.ts b/src/app/components/templates/templates.component.ts deleted file mode 100644 index 05138c8..0000000 --- a/src/app/components/templates/templates.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, Optional, signal, ViewEncapsulation} from '@angular/core'; -import { MatExpansionModule } from '@angular/material/expansion'; -import { MatButtonModule } from '@angular/material/button'; -import { DataService } from '../../services/data.service'; -import { TemplateCategory } from '../../interfaces/template-category.interface'; -import { Template } from '../../interfaces/template.interface'; -import { SyncService } from '../../services/sync.service'; -import { lastValueFrom } from 'rxjs'; -import { MatIconModule } from '@angular/material/icon'; -import { NgClass } from '@angular/common'; -import { MatDialogRef } from '@angular/material/dialog'; - -@Component({ - selector: 'app-templates', - standalone: true, - imports: [MatExpansionModule, MatButtonModule, MatIconModule, NgClass], - templateUrl: './templates.component.html', - styleUrl: './templates.component.scss' -}) -export class TemplatesComponent implements OnInit, AfterViewInit { - @Input() screenWidth: number = 0; - isCollapsed: boolean = false; - - constructor( - private dataService: DataService, - private syncService: SyncService, - @Optional() private dialogRef: MatDialogRef, - private cdr: ChangeDetectorRef - ) { } - - readonly panelOpenState = signal(false); - categories: TemplateCategory[] = []; - - ngOnInit() { - this.categories = this.dataService.templates; - this.cdr.detectChanges(); - } - - ngAfterViewInit(): void { - try { - this.screenWidth = window.innerWidth; - this.cdr.detectChanges(); - } catch (err) { } - } - - async showCode(template: Template) { - this.syncService.setCode(await lastValueFrom(this.dataService.getTemplateCode(template.code))); - this.dialogRef?.close(); - } - - toggleCollapse() { - this.isCollapsed = !this.isCollapsed; - } - - closeDialog() { - this.dialogRef.close(); - } -} diff --git a/src/app/components/toolbar/toolbar.component.html b/src/app/components/toolbar/toolbar.component.html deleted file mode 100644 index dd5b781..0000000 --- a/src/app/components/toolbar/toolbar.component.html +++ /dev/null @@ -1,19 +0,0 @@ -
- -
- - - - @if (screenWidth < 992) { - - } -
-
\ No newline at end of file diff --git a/src/app/components/toolbar/toolbar.component.scss b/src/app/components/toolbar/toolbar.component.scss deleted file mode 100644 index 91ee22c..0000000 --- a/src/app/components/toolbar/toolbar.component.scss +++ /dev/null @@ -1,37 +0,0 @@ -.toolbar-container { - display: flex; - justify-content: space-between; - align-items: center; - height: 7.5svh; - width: 100%; -} - -img { - height: 90%; - margin-left: 1rem; -} - -.control-area { - margin-right: 1rem; -} - -:host-context(.dark-theme) { - .toolbar-container { - border-bottom: 0.5px solid #e6e6e6; - } - - .control-area > button { - color: white; - } - -} - -:host-context(.light-theme) { - .toolbar-container { - border-bottom: 0.5px solid #181818; - } - - .control-area > button { - color: black; - } -} diff --git a/src/app/components/toolbar/toolbar.component.spec.ts b/src/app/components/toolbar/toolbar.component.spec.ts deleted file mode 100644 index 5b58ba7..0000000 --- a/src/app/components/toolbar/toolbar.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { ToolbarComponent } from './toolbar.component'; - -describe('ToolbarComponent', () => { - let component: ToolbarComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ToolbarComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(ToolbarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/components/toolbar/toolbar.component.ts b/src/app/components/toolbar/toolbar.component.ts deleted file mode 100644 index 8b10828..0000000 --- a/src/app/components/toolbar/toolbar.component.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { isPlatformBrowser } from '@angular/common'; -import { AfterViewInit, ChangeDetectorRef, Component, Inject, Input, OnInit, PLATFORM_ID } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatIconModule } from '@angular/material/icon'; -import { MatDialog } from '@angular/material/dialog'; -import { SnackbarService } from '../../services/snackbar.service'; -import { SettingsComponent } from '../settings/settings.component'; -import { TemplatesComponent } from '../templates/templates.component'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { SyncService } from '../../services/sync.service'; - -@Component({ - selector: 'app-toolbar', - standalone: true, - imports: [MatButtonModule, MatIconModule, MatTooltipModule], - templateUrl: './toolbar.component.html', - styleUrl: './toolbar.component.scss' -}) -export class ToolbarComponent implements OnInit, AfterViewInit { - @Input() public screenWidth: number = 0; - public currentTheme: string = 'dark'; - - constructor( - @Inject(PLATFORM_ID) private platformId: any, - private syncService: SyncService, - private snackBar: SnackbarService, - private dialog: MatDialog, - private cdr: ChangeDetectorRef - ) { } - - ngOnInit(): void { - this.currentTheme = this.getSystemTheme(); - this.setTheme(); - this.cdr.detectChanges(); - } - - ngAfterViewInit(): void { - try { - this.screenWidth = window.innerWidth; - this.cdr.detectChanges(); - } catch (err) { } - } - - toggleTheme(): void { - this.currentTheme = this.currentTheme === 'dark' ? 'light' : 'dark'; - this.syncService.setTheme(this.currentTheme); - this.setTheme(); - } - - openDocumentation(): void { - this.snackBar.open('Documentation coming soon!'); - } - - openSettings(): void { - this.dialog.open(SettingsComponent); - } - - openMenu(): void { - this.dialog.open(TemplatesComponent, { - width: '90%' - }); - } - - private getSystemTheme(): string { - return (typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; - } - - private setTheme(): void { - if (isPlatformBrowser(this.platformId)) { - document.body.classList.toggle('dark-theme', this.currentTheme === 'dark'); - document.body.classList.toggle('light-theme', this.currentTheme === 'light'); - } - } -} diff --git a/src/app/directives/screen.directive.spec.ts b/src/app/directives/screen.directive.spec.ts deleted file mode 100644 index 230e2a8..0000000 --- a/src/app/directives/screen.directive.spec.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ScreenDirective } from './screen.directive'; - -describe('ScreenDirective', () => { - it('should create an instance', () => { - const directive = new ScreenDirective(); - expect(directive).toBeTruthy(); - }); -}); \ No newline at end of file diff --git a/src/app/directives/screen.directive.ts b/src/app/directives/screen.directive.ts deleted file mode 100644 index de46a31..0000000 --- a/src/app/directives/screen.directive.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Directive, EventEmitter, HostListener, Output } from '@angular/core'; - -@Directive({ - selector: '[appScreen]', - standalone: true -}) -export class ScreenDirective { - @Output() screenWidth = new EventEmitter(); - @Output() screenHeight = new EventEmitter(); - - constructor() { } - - @HostListener('window:resize', ['$event']) - onResize(event: Event) { - this.screenWidth.emit(window.innerWidth); - this.screenHeight.emit(window.innerHeight); - } - -} \ No newline at end of file diff --git a/src/app/services/sync.service.ts b/src/app/services/sync.service.ts index 518f670..e2075ee 100644 --- a/src/app/services/sync.service.ts +++ b/src/app/services/sync.service.ts @@ -5,7 +5,7 @@ import { BehaviorSubject, Observable } from 'rxjs'; providedIn: 'root' }) export class SyncService { - private code = new BehaviorSubject('// This is a simple "Hello World" program in sQeeZ\nlog("Hello, World!");\n'); + private code = new BehaviorSubject('// This is a simple "Hello World" program in sQeeZ \n\n// Basic log message\nlog("Hello, World!");\n\n// Warning message\nwarn("This is a warning message!");\n\n// Error message\nerror("This is an error message!");\n\n// Colored log message\nlogc("Custom colored message!", #7F00FF);\n'); private output = new BehaviorSubject(''); private fontSize = new BehaviorSubject(16); private tabSize = new BehaviorSubject(2); diff --git a/src/styles.scss b/src/styles.scss index 1fff634..5d84c3e 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -15,10 +15,36 @@ body { .dark-theme { background-color: #222222; + --background-color: #222222; + --font-color: white; + --toolbar: #424242; + --sidenav: #383838; + --content: #303030; + --banner: #222222; + --border: #e6e6e6; + --header: #2d2d2d; + --editor: #1f1f1f; + --console: #181818; + --line-numbers: #6d7681; + --disabled: #f0f0f0; + --highlight: rgba(255, 171, 242, 0.75); } .light-theme { background-color: #f5f5f5; + --background-color: #f5f5f5; + --font-color: black; + --toolbar: #F5F5F5; + --sidenav: #E0E0E0; + --content: #FFFFFF; + --banner: #eeeeee; + --border: #181818; + --header: #e0e0e0; + --editor: #ffffff; + --console: #f8f8f8; + --line-numbers: #6d7681; + --disabled: #f0f0f0; + --highlight: rgba(255, 171, 242, 0.75); } app-root {