From 0c1291da71ce428fc5578b5db2f84f87f9edc270 Mon Sep 17 00:00:00 2001 From: Jan-David Wiederstein <141321444+Datata1@users.noreply.github.com> Date: Tue, 18 Jun 2024 14:40:15 +0200 Subject: [PATCH 1/9] Update .vscodeignore --- .vscodeignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.vscodeignore b/.vscodeignore index b058495..54520f0 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -5,6 +5,8 @@ node_modules/** .yarnrc webpack.config.js vsc-extension-quickstart.md +.codesphere-internal +server **/tsconfig.json **/.eslintrc.json **/*.map From 8d4a6da59a9028424725dbd7055c734c9981fb4c Mon Sep 17 00:00:00 2001 From: jdwiederstein01 Date: Thu, 21 Nov 2024 18:16:46 +0100 Subject: [PATCH 2/9] change dependencies --- package-lock.json | 145 ++++++++++++++++++++++++++++++++++++++++++++-- package.json | 2 +- 2 files changed, 142 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 85c4de2..eb851a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "codesphere", "version": "0.1.11", "dependencies": { - "@vscode/vsce": "^2.26.1", + "@vscode/vsce": "^2.32.0", "ansi-to-html": "^0.7.2", "axios": "^1.6.8", "bufferutil": "^4.0.8", @@ -1212,11 +1212,13 @@ } }, "node_modules/@vscode/vsce": { - "version": "2.26.1", - "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.26.1.tgz", - "integrity": "sha512-QOG6Ht7V93nhwcBxPWcG33UK0qDGEoJdg0xtVeaTN27W6PGdMJUJGTPhB/sNHUIFKwvwzv/zMAHvDgMNXbcwlA==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-2.32.0.tgz", + "integrity": "sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg==", + "license": "MIT", "dependencies": { "@azure/identity": "^4.1.0", + "@vscode/vsce-sign": "^2.0.0", "azure-devops-node-api": "^12.5.0", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", @@ -1250,6 +1252,141 @@ "keytar": "^7.7.0" } }, + "node_modules/@vscode/vsce-sign": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.5.tgz", + "integrity": "sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==", + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optionalDependencies": { + "@vscode/vsce-sign-alpine-arm64": "2.0.2", + "@vscode/vsce-sign-alpine-x64": "2.0.2", + "@vscode/vsce-sign-darwin-arm64": "2.0.2", + "@vscode/vsce-sign-darwin-x64": "2.0.2", + "@vscode/vsce-sign-linux-arm": "2.0.2", + "@vscode/vsce-sign-linux-arm64": "2.0.2", + "@vscode/vsce-sign-linux-x64": "2.0.2", + "@vscode/vsce-sign-win32-arm64": "2.0.2", + "@vscode/vsce-sign-win32-x64": "2.0.2" + } + }, + "node_modules/@vscode/vsce-sign-alpine-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-arm64/-/vsce-sign-alpine-arm64-2.0.2.tgz", + "integrity": "sha512-E80YvqhtZCLUv3YAf9+tIbbqoinWLCO/B3j03yQPbjT3ZIHCliKZlsy1peNc4XNZ5uIb87Jn0HWx/ZbPXviuAQ==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-alpine-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-alpine-x64/-/vsce-sign-alpine-x64-2.0.2.tgz", + "integrity": "sha512-n1WC15MSMvTaeJ5KjWCzo0nzjydwxLyoHiMJHu1Ov0VWTZiddasmOQHekA47tFRycnt4FsQrlkSCTdgHppn6bw==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "alpine" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-arm64/-/vsce-sign-darwin-arm64-2.0.2.tgz", + "integrity": "sha512-rz8F4pMcxPj8fjKAJIfkUT8ycG9CjIp888VY/6pq6cuI2qEzQ0+b5p3xb74CJnBbSC0p2eRVoe+WgNCAxCLtzQ==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-darwin-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-darwin-x64/-/vsce-sign-darwin-x64-2.0.2.tgz", + "integrity": "sha512-MCjPrQ5MY/QVoZ6n0D92jcRb7eYvxAujG/AH2yM6lI0BspvJQxp0o9s5oiAM9r32r9tkLpiy5s2icsbwefAQIw==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm/-/vsce-sign-linux-arm-2.0.2.tgz", + "integrity": "sha512-Fkb5jpbfhZKVw3xwR6t7WYfwKZktVGNXdg1m08uEx1anO0oUPUkoQRsNm4QniL3hmfw0ijg00YA6TrxCRkPVOQ==", + "cpu": [ + "arm" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-arm64/-/vsce-sign-linux-arm64-2.0.2.tgz", + "integrity": "sha512-Ybeu7cA6+/koxszsORXX0OJk9N0GgfHq70Wqi4vv2iJCZvBrOWwcIrxKjvFtwyDgdeQzgPheH5nhLVl5eQy7WA==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-linux-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-linux-x64/-/vsce-sign-linux-x64-2.0.2.tgz", + "integrity": "sha512-NsPPFVtLaTlVJKOiTnO8Cl78LZNWy0Q8iAg+LlBiCDEgC12Gt4WXOSs2pmcIjDYzj2kY4NwdeN1mBTaujYZaPg==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@vscode/vsce-sign-win32-arm64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-arm64/-/vsce-sign-win32-arm64-2.0.2.tgz", + "integrity": "sha512-wPs848ymZ3Ny+Y1Qlyi7mcT6VSigG89FWQnp2qRYCyMhdJxOpA4lDwxzlpL8fG6xC8GjQjGDkwbkWUcCobvksQ==", + "cpu": [ + "arm64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/vsce-sign-win32-x64": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@vscode/vsce-sign-win32-x64/-/vsce-sign-win32-x64-2.0.2.tgz", + "integrity": "sha512-pAiRN6qSAhDM5SVOIxgx+2xnoVUePHbRNC7OD2aOR3WltTKxxF25OfpK8h8UQ7A0BuRkSgREbB59DBlFk4iAeg==", + "cpu": [ + "x64" + ], + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@vscode/vsce/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", diff --git a/package.json b/package.json index 939536d..293100a 100644 --- a/package.json +++ b/package.json @@ -182,7 +182,7 @@ "ws": "^8.16.0" }, "dependencies": { - "@vscode/vsce": "^2.26.1", + "@vscode/vsce": "^2.32.0", "ansi-to-html": "^0.7.2", "axios": "^1.6.8", "bufferutil": "^4.0.8", From 62eeef71fe1aba83c57510731a4834f986139757 Mon Sep 17 00:00:00 2001 From: jdwiederstein01 Date: Thu, 21 Nov 2024 18:17:38 +0100 Subject: [PATCH 3/9] change ci.yaml --- ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci.yml b/ci.yml index 6b6cf4a..a9e538e 100644 --- a/ci.yml +++ b/ci.yml @@ -7,7 +7,7 @@ prepare: - name: Change node version command: sudo -u admin n 18.18.0 - name: Install Dependencies - command: npm install @vscode/vsce + command: npm i - name: Compile project command: npm run compile - name: bundle project From ca0356c876a915fb22e7a746de357ba3120ad7ce Mon Sep 17 00:00:00 2001 From: "jan-david.wiederstein" Date: Sun, 24 Nov 2024 12:32:56 +0100 Subject: [PATCH 4/9] debug ci-pipeline false initial run stage button status --- src/CiPipelineProvider.ts | 1 + webviews/components/CiPipeline.svelte | 33 ++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/CiPipelineProvider.ts b/src/CiPipelineProvider.ts index 57c12ab..c3eb537 100644 --- a/src/CiPipelineProvider.ts +++ b/src/CiPipelineProvider.ts @@ -58,6 +58,7 @@ export class CiPipelineProvider implements vscode.WebviewViewProvider { const ciPipelineCheck = checkCiPipelineStructure(uaSocket, 324); ciPipelineCheck.then((ci: any) => { ciStructure = ci; + console.log("ciStructure: ", JSON.stringify(ciStructure)); this._view?.webview.postMessage({ type: "CIPipelineStages", value: { diff --git a/webviews/components/CiPipeline.svelte b/webviews/components/CiPipeline.svelte index 6f9336f..5f9034c 100644 --- a/webviews/components/CiPipeline.svelte +++ b/webviews/components/CiPipeline.svelte @@ -45,21 +45,30 @@ } step.open = false }); - prepareStageSteps[0].open = true; + + if (stagelength > 0) { + prepareStageSteps[0].open = true + } } if (stage == "test") { stageRunning = [...stageRunning, stage] testStageSate = true; testStageSuccess = ''; stagelength = testStageSteps.length - testStageSteps[0].open = true + + if (stagelength > 0) { + testStageSteps[0].open = true + } } if (stage == "run") { stageRunning = [...stageRunning, stage] runStageSate = true; runStageSuccess = ''; stagelength = runStageSteps.length - runStageSteps[0].open = true + + if (stagelength > 0) { + runStageSteps[0].open = true + } } vscode.postMessage({ type: 'startCiStage', @@ -120,6 +129,10 @@ currentWorkspace = message.value.currentWorkspace; teamId = message.value.teamId; dcId = message.value.dcId; + + console.log("currentWorkspace", currentWorkspace); + console.log("teamId", teamId); + console.log("dcId", dcId); vscode.postMessage({ type: 'getCiPipelineStages', @@ -174,6 +187,7 @@ break; case 'ciPipelineStatus': if (message.value.dynamic) { + console.log("dynamic", message.value.dynamic); switch (message.value.dynamic) { case 'prepare': prepareStageSuccess = message.value.prepare.state; @@ -182,6 +196,8 @@ }); if (prepareStageSuccess === 'running') { prepareStageSate = true; + stageRunning = [...stageRunning, 'prepare'] + } if (prepareStageSuccess === 'success' || prepareStageSuccess === 'failure') { prepareStageSate = false; @@ -194,6 +210,8 @@ }); if (testStageSuccess === 'running') { testStageSate = true; + stageRunning = [...stageRunning, 'test'] + } if (testStageSuccess === 'success' || testStageSuccess === 'failure') { testStageSate = false; @@ -206,6 +224,7 @@ }); if (runStageSuccess === 'running') { runStageSate = true; + stageRunning = [...stageRunning, 'run'] } if (runStageSuccess === 'success' || runStageSuccess === 'failure') { runStageSate = false; @@ -216,12 +235,15 @@ } if (message.value.dynamic === false && message.value.prepare.state){ + console.log("prepare dynamic false", message.value.prepare.state); prepareStageSuccess = message.value.prepare.state; prepareStageSteps.forEach(( step, index) => { Object.assign(step, message.value.prepare.steps[index]); }); if (prepareStageSuccess === 'running') { prepareStageSate = true; + stageRunning = [...stageRunning, 'prepare'] + } if (prepareStageSuccess === 'success' || prepareStageSuccess === 'failure') { prepareStageSate = false; @@ -229,12 +251,15 @@ } if (message.value.dynamic === false && message.value.test.state){ + console.log("test dynamic false", message.value.test.state); testStageSuccess = message.value.test.state; testStageSteps.forEach(( step, index) => { Object.assign(step, message.value.test.steps[index]); }); if (testStageSuccess === 'running') { testStageSate = true; + stageRunning = [...stageRunning, 'test'] + } if (testStageSuccess === 'success' || testStageSuccess === 'failure') { testStageSate = false; @@ -242,12 +267,14 @@ } if (message.value.dynamic === false && message.value.run.state){ + console.log("run dynamic false", message.value.run.state); runStageSuccess = message.value.run.state; runStageSteps.forEach(( step, index) => { Object.assign(step, message.value.run.steps[index]); }); if (runStageSuccess === 'running') { runStageSate = true; + stageRunning = [...stageRunning, 'run'] } if (runStageSuccess === 'success' || runStageSuccess === 'failure') { runStageSate = false; From 3278468a2f8c4c1c7c787180cd6fa4e988458d07 Mon Sep 17 00:00:00 2001 From: "jan-david.wiederstein" Date: Sun, 24 Nov 2024 12:59:02 +0100 Subject: [PATCH 5/9] improve restore window behavior. Only disable it when inside tunnel. This is mandatory, because when off-when-unused workspaces shut down, then the local vscode client cannot initiate properly and we cannot control vscode before the tunnel connection is up. This is a rather sad solution because in THEORY we could control the behavior before vscode's tries to open the tunnel connection, but this API is since 2019 proposal API and it very unlikly that microsoft will change it. Only microsoft extensions are allowed to use proposed API in production vscode and if we want to use such proposed API we need vscode insiders. No casual user has vscode insiders installed. This is the most simple solution to that problem but i dont like that we interfere with global user settings. Why does microsoft allow to change global user settings? I could create an extension and destroy all the user settings of anyone who install my extension. Why is that even possible?! --- src/extension.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 7473360..163d3b5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -25,9 +25,6 @@ export function activate(context: vscode.ExtensionContext) { const fileTreeProvider = new FileTreeProvider(rootPath); const ciPipelineProvider = new CiPipelineProvider(context.extensionUri, context); - //TODO: the line below disables vscode to remember the last opened windows. - // change it that it only disables it inside remote tunnels - vscode.workspace.getConfiguration('window').update('restoreWindows', 'none', vscode.ConfigurationTarget.Global); context.subscriptions.push( vscode.window.registerWebviewViewProvider( @@ -100,7 +97,10 @@ export function activate(context: vscode.ExtensionContext) { if (workspaceId !== "" && workspaceId !== "$WORKSPACE_ID") { const pwdUri = vscode.Uri.parse('home/user/app'); + vscode.workspace.getConfiguration('window').update('restoreWindows', 'none', vscode.ConfigurationTarget.Global); vscode.commands.executeCommand('vscode.openFolder', pwdUri); + } else { + vscode.workspace.getConfiguration('window').update('restoreWindows', 'all', vscode.ConfigurationTarget.Global); } }); From ed4380a817bd512b6acb7c17cf5c69fd1b18a9c9 Mon Sep 17 00:00:00 2001 From: "jan-david.wiederstein" Date: Sun, 24 Nov 2024 13:41:48 +0100 Subject: [PATCH 6/9] test debug --- src/SidebarProvider.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/SidebarProvider.ts b/src/SidebarProvider.ts index 824ab7d..bb61491 100644 --- a/src/SidebarProvider.ts +++ b/src/SidebarProvider.ts @@ -66,9 +66,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider { vscode.commands.executeCommand('setContext', 'codesphere.isLoggedIn', true); cache.update("codesphere.isLoggedIn", true); webviewView.webview.html = this._getHtmlWebviewOverview(webviewView.webview); - cache.update('codesphere.workspaceOverview', cache.get('codesphere.currentWorkspace')); - vscode.commands.executeCommand('setContext', 'codesphere.workspaceOverview', cache.get('codesphere.currentWorkspace')); - console.log('Congratulations, your extension "codesphere" is now active! You are logged in.'); + // todo: instead of passing just the workspace id we need to pass the whole workspace object let currentWorkspace = parseInt(cache.get('codesphere.currentWorkspace') as string); const workspacesInTeam: any = cache.get("codesphere.workspaces"); @@ -86,7 +84,9 @@ export class SidebarProvider implements vscode.WebviewViewProvider { break; } } - cache.update("codesphere.currentconnectedWorkspace", matchingObject); + + console.log('matchingObject', matchingObject); + cache.update("codesphere.workspaceOverview", matchingObject); if (matchingObject) { this._view?.webview.postMessage({ @@ -96,6 +96,10 @@ export class SidebarProvider implements vscode.WebviewViewProvider { }, }); } + + // cache.update('codesphere.workspaceOverview', cache.get('codesphere.currentWorkspace')); + vscode.commands.executeCommand('setContext', 'codesphere.workspaceOverview', cache.get('codesphere.currentWorkspace')); + console.log('Congratulations, your extension "codesphere" is now active! You are logged in.'); } if (!cache.get("codesphere.isLoggedIn")) { From 987396c4e18aacf452c63d8336413c22a8fc2127 Mon Sep 17 00:00:00 2001 From: "jan-david.wiederstein" Date: Sun, 24 Nov 2024 14:08:20 +0100 Subject: [PATCH 7/9] fix initial state bugs --- src/SidebarProvider.ts | 2 +- src/extension.ts | 7 ++++++- webviews/components/Overview.svelte | 14 ++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/SidebarProvider.ts b/src/SidebarProvider.ts index bb61491..323bf80 100644 --- a/src/SidebarProvider.ts +++ b/src/SidebarProvider.ts @@ -55,7 +55,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider { } - if (cache.get("codesphere.isLoggedIn") === true) { + if (cache.get("codesphere.isLoggedIn") === true && cache.get('codesphere.currentWorkspace') === '') { vscode.commands.executeCommand('setContext', 'codesphere.isLoggedIn', true); cache.update("codesphere.isLoggedIn", true); webviewView.webview.html = this._getHtmlForWebviewAfterSignIn(webviewView.webview); diff --git a/src/extension.ts b/src/extension.ts index 163d3b5..1cf654d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -29,7 +29,12 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push( vscode.window.registerWebviewViewProvider( "codesphere-sidebar", - sidebarProvider + sidebarProvider, + { + webviewOptions: { + retainContextWhenHidden: true + } + } ) ); diff --git a/webviews/components/Overview.svelte b/webviews/components/Overview.svelte index ba1ad5d..ae60cf3 100644 --- a/webviews/components/Overview.svelte +++ b/webviews/components/Overview.svelte @@ -561,7 +561,7 @@ {/if} - {#if activeWorkspace === true && workspaceDeployed === true && connectedWorkspace === false} + {#if activeWorkspace === true && workspaceDeployed === true} -
-
- - + {#if connectedWorkspace === false} +
+
+ + +
-
+ {/if} {/if}
\ No newline at end of file From 0a03fb31fcf35e2cd68cf60a3d2b332cb85803a2 Mon Sep 17 00:00:00 2001 From: "jan-david.wiederstein" Date: Sun, 24 Nov 2024 14:48:09 +0100 Subject: [PATCH 8/9] remove scroll bar workspace overview --- webviews/components/Codesphere.svelte | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/webviews/components/Codesphere.svelte b/webviews/components/Codesphere.svelte index 7880c38..eee2cb9 100644 --- a/webviews/components/Codesphere.svelte +++ b/webviews/components/Codesphere.svelte @@ -213,17 +213,24 @@ color: white!important; } - .workspaceList { + .workspaceList { position: relative; - overflow-x: auto; + overflow-x: auto; white-space: nowrap; padding-left: 16px; } - .workspaceList:nth-child(2) { + .workspaceList:nth-child(1) { padding-top:8px } + + + .workspaceList { + scrollbar-width: none; + -ms-overflow-style: none; + } + .workspaceBox { display: flex; flex-direction: column; @@ -249,10 +256,12 @@ } .height-indicator { + margin: 0; + margin-bottom: -8px; position: absolute; left: 8px; height: 100%; - border-left: .5px solid #80808026;; + border-left: 1.8px solid #80808026; } From 3866700cbda786cc8c8b1bda2ff0c316dddcf068 Mon Sep 17 00:00:00 2001 From: Jan-David Wiederstein Date: Sun, 24 Nov 2024 15:31:00 +0100 Subject: [PATCH 9/9] add user avatar placeholder when not available --- webviews/components/Codesphere.svelte | 44 ++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/webviews/components/Codesphere.svelte b/webviews/components/Codesphere.svelte index eee2cb9..5c0932d 100644 --- a/webviews/components/Codesphere.svelte +++ b/webviews/components/Codesphere.svelte @@ -12,6 +12,7 @@ let notDeployedWorkspaces = []; let indexOfWorkspace; let currentWorkspace; + let username; function openOverview(workspaceId, teamId) { vscode.postMessage({ @@ -93,6 +94,10 @@ break; case 'getUserData': user = JSON.parse(message.value); + console.log("User: " , user); + if (user.avatarURL === null) { + username = getInitials(user); + } break; case 'activeWorkspaces': activeWorkspaces = message.value; @@ -148,6 +153,26 @@ const teamIndex = teamArray.findIndex(team => team.id === teamId); teamArray[teamIndex].open = !teamArray[teamIndex].open; } + + function getInitials(user) { + console.log("User Names: ", user.firstName, user.lastName, user.email); + + if (user.firstName && user.lastName) { + return user.firstName[0].toUpperCase() + user.lastName[0].toUpperCase(); + } + + if (user.firstName) { + return user.firstName[0].toUpperCase(); + } + + if (user.lastName) { + return user.lastName[0].toUpperCase(); + } + + if (user.email) { + return user.email[0].toUpperCase(); + } + } @@ -200,6 +225,17 @@ height: 32px; border-radius: 50%; object-fit: cover; + display: flex; + align-items: center; + justify-content: center; + font-size: 1rem; + font-weight: bold; + color: white; + text-transform: uppercase; + } + + .defaultAvatar { + background-color: #80808026; } .workspace { @@ -270,7 +306,13 @@

Your Teams

- User Avatar + {#if user.avatarURL} + User Avatar + {:else} +
+ {username} +
+ {/if}
{#each teamArray as team (team.id)}