border-black border-solid border-2border-black border-solid border-2Poem Database
- Remove
+ Add { $poems = $poems.toSpliced($i || 0, 1, props.value); }">some text0 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Just playing into the future
What Alex asked me to do
How you are describing it is actually counterintuitive
I want it simple
But what does simple mean?
Let’s get rid of all this fluff down here
A user should never have a dead end
Let’s not apologize for anything
And that’s the way it works
I see your point
Some of this stuff doesn’t make sense">some text1 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="There’s no limitation
We just need to put the damn data in there
Just put the date
We’re going to play the same team same defense
It’s so simple
You have to stop doing it your own way
I want them to clean their boards
If I pull the data from all the boards
You’re going to get shit
Make it compliant
That’s it
You don’t like the standard, have a conversation, that’s fine
Otherwise you’re going to have a private conversation
Excuse my board
Not to get stuck in the philosophical
Many companies have these matrix teams
Design by committee
This is the way we're going to compensate
Ok
Sounds good
Amazing
Since we’re doing garbage time round up
Shits hitting the fan
I don’t want to build that ever again
That things obsolete dude
It put their members in an impossible state
Don’t worry about it
This is like zeroes and ones
How do we make sushi?
What are we building?
When is it going live?
What problems are we having?">some text2 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="A year is not a lot
Let's not make an urgent move
Use the carrot and not the stick
Bulletize these
A new simplified way
Super ready
We are off track a lot
We have so many fields
Where is Asana?
It's just too much
One of the things I think is the best things in life
You kind of blend a lot of seeds
And it's like oh my god this is amazing
Let's just like steal with pride
Everybody adopts, yeah?
Such an important point
This is lovely
You got to look at how the gap is closing
Just to start book-ending it
A nice sense of urgency
Right now it's like who knows
It's totally up to the gods
I can do it myself
I'm going to keep pushing and pushing
How are we even doing this
Blah, blah, blah
I am expecting you to wrestle this down
It's your guy's job to call bullshit on this
Prove me wrong
I'd love to see it
Find your rhythm
We've done it and done it and done it
Are they getting a PHD in shit we will never use?
How is this going to take you four hours?
We have to wrestle this down
I need this implemented fast
That's it, go to work">some text3 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Significant doubts
I have doubts that live on two levels
Maybe it’s not a mess">some text4 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="You see we have so many time
People will get used to it
You know what essence is actually
We are trying not to interfere with essence
I think this view right here is over-redundant
I just want to ask questions
I think we are all saying the same thing
It’s just ones and zeroes
We can solve all these problems don’t worry
Once again
Right, once again
I want this button right here, that’s it!
And I don’t want it
It’s like a back door
Can I please speak?
Do not use that language
Please I beg you
You’re talking about the wrong thing
All I was saying
We will crush it
We will buy months to bring out the next iteration
Henrik is going to throw the towel at my face
Let’s calm down
Once again
Let’s elevate the discussion a bit
There’s no technical constraint
It’s all design
Once again
Wait a second
It’s ugly but it’s a solution
Wait a second
It takes valuable real estate and does nothing
You will have all the time in the world
I love that everyone’s passionate">some text5 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="No dead ends
We always have to guide them to the next step
Even trick them with a different message
You can actually book in the past
When, when, when, when!
We should not sleep anymore
We’ve got to get this thing out">some text6 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Why is there no preloading?
Why is there no photo for this user?
Oh my god this looks so much better already
Less is always more beautiful
Don’t do that
No, no, no
No, don’t do that ever
We discussed this yesterday, come on
This looks so much better
Massive, massive difference
I think it’s still busy
Can we find that avatar and crush it
I was really worried guys but I’m feeling better now
That should never be possible
Right now it’s possible
SMS is a super in the moment medium">some text7 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Push vs. pull
Constant communication
Document, document, document
We're probably going to have 3 or 5 of those
Oh shit
A lot more work and bullshit">some text8 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="You wouldn’t believe the things I’ve heard in this office
I’m sitting on everyone I come into
I’m not this dumb
Sorry, it’s no
No, no, no, no, no
I was like holy moly
I don’t want to know at this point
Maybe you got to break a couple rules before… I don’t know
That really wasted 20 minutes of my time">some text9 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Raphi was going to put a million bucks
They raised money at a $40 million dollar valuation
They’re scam artists that don’t have shit
I had a dream last night
We ended up going to a midget strip club
That’s like wearing a house on your wrist">some text10 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Super ads
It’s absolutely amazing
It’s literally amazing
It’s an unbelievable platform
This is a huge one for us guys
3-4% is just astronomical
Very very important for organic">some text11 { $poems = $poems.toSpliced($i || 0, 1, props.value); }" value="Let’s figure out how to reformat and recirculate
The unknown is a little scary
I’ll shut up now
Let’s circle back to priorities and we’ll circle right back to this
Support needs to know exactly what’s going to break
Let’s refactor the way we utilize them today
Micro-breakouts
We can circle back to kind of other tasks
When your in the weeds no one wants to hear slow down, get down and document
So then we take ownership of building a manifesto
Not even try, find please, an hour with everyone on
Tuesdays and Thursdays are hard because I have to sneak out
What’s our marching kind of orders
Kind of fill in some of that color
Jerry will be sprinkled in
All guns blazing, very eager to get some points on the board
The happy ending will be getting some of those data issues resolved
Non-developer mindset
The big win is we’ve got the proper mindset">some textDebugblockTree["Ax0"].block.store;Zoom Poems1 of 12 1 ? $poem_index -= 1 : null" x="1966" y="1261" class="bg-green-500 w-32 text-white rounded-sm cursor-pointer py-2 text-sm text-gray-700 hover:bg-blue-400 active:bg-blue-600" disabled="1">< PreviousNext >Just playing into the future What Alex asked me to do How you are describing it is actually counterintuitive I want it simple But what does simple mean? Let’s get rid of all this fluff down here A user should never have a dead end Let’s not apologize for anything And that’s the way it works I see your point Some of this stuff doesn’t make senseGo to developement world 🌎Go to designer world 🌎Guest BookAdd your name to the guest book if you gave us a visit!Go to debugger world 🌎Go to the Peoplevine world 🌿Playground.blocks.world-block.jsexport default class World extends Block {
tagName = "world-block";
render = `
<style>
.world {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.world::before {
z-index: -1;
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
text-align: center;
background: white; /*#22333b*/;
}
.space {
position: absolute;
top: 0;
left: 0;
width: 4096px;
height: 4096px;
background-size: 32px 32px;
background-image: linear-gradient(
to right,
rgba(40, 126, 255, 0.1) 1px,
transparent 1px
),
linear-gradient(to bottom, rgba(40, 126, 255, 0.1) 1px, transparent 1px);
transform: translate3d(0, 0, 0);
}
</style>
<div class="world">
<div class="space">
<slot>
</div>
</div>
`;
connectedCallback() {
super.connectedCallback();
this.rootElement = true;
this.shadowWorld = this.shadowRoot.querySelector(".world");
this.space = this.shadowRoot.querySelector(".space");
this.buildBlockTree();
this.store.meta = false;
const playerId = localStorage.getItem("playerId") || crypto.randomUUID();
localStorage.setItem("playerId", playerId);
this.store.playerId = playerId;
this.observer = new MutationObserver((record) => {
const hasBlocks = (arr) =>
Array.isArray(arr) &&
arr.some((el) => el.tagName?.toLowerCase().endsWith("block"));
const added = record
.map((r) => Array.from(r.addedNodes))
.filter(hasBlocks)
.flat(2);
const removed = record
.map((r) => Array.from(r.removedNodes))
.filter(hasBlocks)
.flat(2);
if (![...added, ...removed].length) {
return;
}
this.buildBlockTree(added, removed);
});
this.observer.observe(this, {
childList: true,
subtree: true,
});
/* this.saveObserver.observe(this, {
childList: true,
subtree: true,
attributes: true,
}); */
this.scrollX = Number(this.getAttribute("scroll-x")) || 0;
this.scrollY = Number(this.getAttribute("scroll-y")) || 0;
this.shadowWorld.addEventListener("wheel", this.handleScroll.bind(this), {
passive: false,
});
if (!this.hasAttribute("scroll-x") && !this.hasAttribute("scroll-y")) {
this.scrollX =
(this.space.offsetWidth - this.shadowWorld.offsetWidth) / 2;
this.scrollY =
(this.space.offsetHeight - this.shadowWorld.offsetHeight) / 2;
this.setAttribute("scroll-x", this.scrollX);
this.setAttribute("scroll-y", this.scrollY);
}
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px)`;
this.isDragging = false;
/*this.shadowWorld.addEventListener(
"touchstart",
this.handleTouchStart.bind(this),
);
this.shadowWorld.addEventListener(
"touchmove",
this.handleTouchMove.bind(this),
);
this.shadowWorld.addEventListener(
"touchend",
this.handleTouchEnd.bind(this),
);*/
this.shadowWorld.addEventListener("click", this.click);
document.addEventListener("keyup", (e) => {
this.store.meta = false;
});
// Command+K to open spotlight
document.addEventListener("keydown", (e) => {
if (e.metaKey || e.ctrlKey) {
this.store.meta = true;
}
if (
e.keyCode === 83 &&
(navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)
) {
// CMD+S / CTRL+S
e.preventDefault();
}
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
e.preventDefault();
if (!document.querySelector("spotlight-block")) {
const spotlight = document.createElement("spotlight-block");
spotlight.setAttribute("fixed", "");
document.body.appendChild(spotlight);
} else {
const spotlight = document.querySelector("spotlight-block");
spotlight.remove();
}
}
});
}
disconnectedCallback() {
super.disconnectedCallback && super.disconnectedCallback();
this.observer && this.observer.disconnect();
}
isAncestorScrollable(el) {
let node = el;
while (node && node !== document.body) {
const hasScrollableContent = node.scrollHeight > node.clientHeight;
const overflowYStyle = window.getComputedStyle(node).overflowY;
const isOverflowHidden = overflowYStyle.indexOf("hidden") !== -1;
const canScroll = hasScrollableContent && !isOverflowHidden;
if (canScroll) {
return true;
}
node = node.parentElement;
if (node && node.tagName === "world-block") return false;
}
return false;
}
handleScroll(e) {
e.preventDefault();
if (this.isAncestorScrollable(e.target)) {
//return;
}
if (e.target.tagName === "code-block") return;
// Don't scroll if context menu is open
const spotlightBlock = document.querySelector("spotlight-block");
const menuBlocks = document.querySelectorAll("menu-block");
if (menuBlocks.length || spotlightBlock) return;
if (e.ctrlKey) {
const scale = this.scale || 1;
const delta = -e.deltaY * 0.001;
const newScale = Math.max(0.1, Math.min(3, scale + delta));
this.scale = newScale;
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px) scale(${newScale})`;
return;
}
const newScrollX = this.scrollX + e.deltaX;
const newScrollY = this.scrollY + e.deltaY;
const maxScrollX = this.space.offsetWidth - this.shadowWorld.offsetWidth;
const maxScrollY = this.space.offsetHeight - this.shadowWorld.offsetHeight;
this.scrollX = Math.max(0, Math.min(newScrollX, maxScrollX));
this.scrollY = Math.max(0, Math.min(newScrollY, maxScrollY));
// Update attributes
this.setAttribute("scroll-x", this.scrollX);
this.setAttribute("scroll-y", this.scrollY);
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px) ${
this.scale ? `scale(${this.scale})` : ""
}`;
}
handleTouchStart(event) {
event.preventDefault();
this.isDragging = true;
this.lastTouchX = event.touches[0].clientX;
this.lastTouchY = event.touches[0].clientY;
}
handleTouchMove(e) {
if (!this.isDragging) return;
e.preventDefault();
const touch = e.touches[0];
const deltaX = this.lastTouchX - touch.clientX;
const deltaY = this.lastTouchY - touch.clientY;
this.updateScroll(deltaX, deltaY);
this.lastTouchX = touch.clientX;
this.lastTouchY = touch.clientY;
}
handleTouchEnd() {
this.isDragging = false;
}
updateScroll(deltaX, deltaY) {
const newScrollX = this.scrollX + deltaX;
const newScrollY = this.scrollY + deltaY;
const maxScrollX = this.space.offsetWidth - this.shadowWorld.offsetWidth;
const maxScrollY = this.space.offsetHeight - this.shadowWorld.offsetHeight;
this.scrollX = Math.max(0, Math.min(newScrollX, maxScrollX));
this.scrollY = Math.max(0, Math.min(newScrollY, maxScrollY));
this.setAttribute("scroll-x", this.scrollX);
this.setAttribute("scroll-y", this.scrollY);
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px)`;
}
click() {
const toolbars = document.querySelectorAll("toolbar-block");
toolbars.forEach((toolbar) => toolbar.remove());
}
nextSpreadsheetLetter(char) {
let carry = 1;
let res = "";
for (let i = char.length - 1; i >= 0; i--) {
let charCode = char.charCodeAt(i) - 65 + carry;
if (charCode === 26) {
res = "A" + res;
carry = 1;
} else {
res = String.fromCharCode((charCode % 26) + 65) + res;
carry = 0;
}
}
if (carry === 1) res = "A" + res;
return res;
}
buildBlockTree(added, removed) {
/* if (window.blockTree) {
if (added) {
for (let el of added) {
const parent = Object.values(window.blockTree).find((node) => node.block === added);
console.log(parent);
}
}
return;
} */
//console.time("build-block-tree");
let currentNode = null;
let rowCounts = {
A: 0,
};
let todo = [
{
parent: null,
position: "Ax0",
block: this,
},
];
window.blockTree = {
Ax0: { block: this },
};
while (todo.length) {
currentNode = todo.shift();
let [row] = currentNode.position.split("x");
const childRow = this.nextSpreadsheetLetter(row);
for (let child of Array.from(currentNode.block.childNodes || [])) {
if (!child.tagName?.toLowerCase().endsWith("block")) {
continue;
}
const childColumn = ++rowCounts[childRow] || (rowCounts[childRow] = 1);
const node = {
parent: currentNode.position,
position: childRow + "x" + childColumn,
block: child,
};
const { position: _, ...nodeWithoutPosition } = node;
window.blockTree[node.position] = nodeWithoutPosition;
if (child.childNodes) {
todo.push(node);
}
}
}
//console.timeEnd("build-block-tree");
}
}
Kit BrowserZoom PoemsPlaygroundPeoplevineFirst SpinblocksscriptsCreate BlockCreateWorldKit BrowserTextareaCursorWindowTextFirst Spin PrototypeFlexSpotlightDropdownSceneRepeatTinaLinkInputMenu ItemSpotlight NavHighlightScript LoggerStage ManagerCodeImageToolbarButtonMenuPlayground.blocks.world-block.jsexport default class World extends Block {
tagName = "world-block";
render = `
<style>
.world {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.world::before {
z-index: -1;
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
text-align: center;
background: white; /*#22333b*/;
}
.space {
position: absolute;
top: 0;
left: 0;
width: 4096px;
height: 4096px;
background-size: 32px 32px;
background-image: linear-gradient(
to right,
rgba(40, 126, 255, 0.1) 1px,
transparent 1px
),
linear-gradient(to bottom, rgba(40, 126, 255, 0.1) 1px, transparent 1px);
transform: translate3d(0, 0, 0);
}
</style>
<div class="world">
<div class="space">
<slot>
</div>
</div>
`;
connectedCallback() {
super.connectedCallback();
this.rootElement = true;
this.shadowWorld = this.shadowRoot.querySelector(".world");
this.space = this.shadowRoot.querySelector(".space");
this.buildBlockTree();
this.store.meta = false;
const playerId = localStorage.getItem("playerId") || crypto.randomUUID();
localStorage.setItem("playerId", playerId);
this.store.playerId = playerId;
this.observer = new MutationObserver((record) => {
const hasBlocks = (arr) =>
Array.isArray(arr) &&
arr.some((el) => el.tagName?.toLowerCase().endsWith("block"));
const added = record
.map((r) => Array.from(r.addedNodes))
.filter(hasBlocks)
.flat(2);
const removed = record
.map((r) => Array.from(r.removedNodes))
.filter(hasBlocks)
.flat(2);
if (![...added, ...removed].length) {
return;
}
this.buildBlockTree(added, removed);
});
this.observer.observe(this, {
childList: true,
subtree: true,
});
/* this.saveObserver.observe(this, {
childList: true,
subtree: true,
attributes: true,
}); */
this.scrollX = Number(this.getAttribute("scroll-x")) || 0;
this.scrollY = Number(this.getAttribute("scroll-y")) || 0;
this.shadowWorld.addEventListener("wheel", this.handleScroll.bind(this), {
passive: false,
});
if (!this.hasAttribute("scroll-x") && !this.hasAttribute("scroll-y")) {
this.scrollX =
(this.space.offsetWidth - this.shadowWorld.offsetWidth) / 2;
this.scrollY =
(this.space.offsetHeight - this.shadowWorld.offsetHeight) / 2;
this.setAttribute("scroll-x", this.scrollX);
this.setAttribute("scroll-y", this.scrollY);
}
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px)`;
this.isDragging = false;
/*this.shadowWorld.addEventListener(
"touchstart",
this.handleTouchStart.bind(this),
);
this.shadowWorld.addEventListener(
"touchmove",
this.handleTouchMove.bind(this),
);
this.shadowWorld.addEventListener(
"touchend",
this.handleTouchEnd.bind(this),
);*/
this.shadowWorld.addEventListener("click", this.click);
document.addEventListener("keyup", (e) => {
this.store.meta = false;
});
// Command+K to open spotlight
document.addEventListener("keydown", (e) => {
if (e.metaKey || e.ctrlKey) {
this.store.meta = true;
}
if (
e.keyCode === 83 &&
(navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey)
) {
// CMD+S / CTRL+S
e.preventDefault();
}
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
e.preventDefault();
if (!document.querySelector("spotlight-block")) {
const spotlight = document.createElement("spotlight-block");
spotlight.setAttribute("fixed", "");
document.body.appendChild(spotlight);
} else {
const spotlight = document.querySelector("spotlight-block");
spotlight.remove();
}
}
});
}
disconnectedCallback() {
super.disconnectedCallback && super.disconnectedCallback();
this.observer && this.observer.disconnect();
}
isAncestorScrollable(el) {
let node = el;
while (node && node !== document.body) {
const hasScrollableContent = node.scrollHeight > node.clientHeight;
const overflowYStyle = window.getComputedStyle(node).overflowY;
const isOverflowHidden = overflowYStyle.indexOf("hidden") !== -1;
const canScroll = hasScrollableContent && !isOverflowHidden;
if (canScroll) {
return true;
}
node = node.parentElement;
if (node && node.tagName === "world-block") return false;
}
return false;
}
handleScroll(e) {
e.preventDefault();
if (this.isAncestorScrollable(e.target)) {
//return;
}
if (e.target.tagName === "code-block") return;
// Don't scroll if context menu is open
const spotlightBlock = document.querySelector("spotlight-block");
const menuBlocks = document.querySelectorAll("menu-block");
if (menuBlocks.length || spotlightBlock) return;
if (e.ctrlKey) {
const scale = this.scale || 1;
const delta = -e.deltaY * 0.001;
const newScale = Math.max(0.1, Math.min(3, scale + delta));
this.scale = newScale;
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px) scale(${newScale})`;
return;
}
const newScrollX = this.scrollX + e.deltaX;
const newScrollY = this.scrollY + e.deltaY;
const maxScrollX = this.space.offsetWidth - this.shadowWorld.offsetWidth;
const maxScrollY = this.space.offsetHeight - this.shadowWorld.offsetHeight;
this.scrollX = Math.max(0, Math.min(newScrollX, maxScrollX));
this.scrollY = Math.max(0, Math.min(newScrollY, maxScrollY));
// Update attributes
this.setAttribute("scroll-x", this.scrollX);
this.setAttribute("scroll-y", this.scrollY);
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px) ${
this.scale ? `scale(${this.scale})` : ""
}`;
}
handleTouchStart(event) {
event.preventDefault();
this.isDragging = true;
this.lastTouchX = event.touches[0].clientX;
this.lastTouchY = event.touches[0].clientY;
}
handleTouchMove(e) {
if (!this.isDragging) return;
e.preventDefault();
const touch = e.touches[0];
const deltaX = this.lastTouchX - touch.clientX;
const deltaY = this.lastTouchY - touch.clientY;
this.updateScroll(deltaX, deltaY);
this.lastTouchX = touch.clientX;
this.lastTouchY = touch.clientY;
}
handleTouchEnd() {
this.isDragging = false;
}
updateScroll(deltaX, deltaY) {
const newScrollX = this.scrollX + deltaX;
const newScrollY = this.scrollY + deltaY;
const maxScrollX = this.space.offsetWidth - this.shadowWorld.offsetWidth;
const maxScrollY = this.space.offsetHeight - this.shadowWorld.offsetHeight;
this.scrollX = Math.max(0, Math.min(newScrollX, maxScrollX));
this.scrollY = Math.max(0, Math.min(newScrollY, maxScrollY));
this.setAttribute("scroll-x", this.scrollX);
this.setAttribute("scroll-y", this.scrollY);
this.space.style.transform = `translate(${-this.scrollX}px, ${-this.scrollY}px)`;
}
click() {
const toolbars = document.querySelectorAll("toolbar-block");
toolbars.forEach((toolbar) => toolbar.remove());
}
nextSpreadsheetLetter(char) {
let carry = 1;
let res = "";
for (let i = char.length - 1; i >= 0; i--) {
let charCode = char.charCodeAt(i) - 65 + carry;
if (charCode === 26) {
res = "A" + res;
carry = 1;
} else {
res = String.fromCharCode((charCode % 26) + 65) + res;
carry = 0;
}
}
if (carry === 1) res = "A" + res;
return res;
}
buildBlockTree(added, removed) {
/* if (window.blockTree) {
if (added) {
for (let el of added) {
const parent = Object.values(window.blockTree).find((node) => node.block === added);
console.log(parent);
}
}
return;
} */
//console.time("build-block-tree");
let currentNode = null;
let rowCounts = {
A: 0,
};
let todo = [
{
parent: null,
position: "Ax0",
block: this,
},
];
window.blockTree = {
Ax0: { block: this },
};
while (todo.length) {
currentNode = todo.shift();
let [row] = currentNode.position.split("x");
const childRow = this.nextSpreadsheetLetter(row);
for (let child of Array.from(currentNode.block.childNodes || [])) {
if (!child.tagName?.toLowerCase().endsWith("block")) {
continue;
}
const childColumn = ++rowCounts[childRow] || (rowCounts[childRow] = 1);
const node = {
parent: currentNode.position,
position: childRow + "x" + childColumn,
block: child,
};
const { position: _, ...nodeWithoutPosition } = node;
window.blockTree[node.position] = nodeWithoutPosition;
if (child.childNodes) {
todo.push(node);
}
}
}
//console.timeEnd("build-block-tree");
}
}
Playground.blocks.button-block.jsexport default class Button extends Block {
tagName = "button-block";
static defaultAttributes = {
class: "bg-gray-100 rounded-sm cursor-pointer px-4 py-2 text-sm text-gray-700 hover:bg-gray-200",
};
render = `
<button>
<slot>
</button>
`;
connectedCallback() {
super.connectedCallback();
this.button = this.shadowRoot.querySelector("button");
const slot = this.shadowRoot.querySelector("slot");
if (slot.assignedNodes().length === 0) {
this.button.textContent = "my awesome button";
}
}
}
Playground.scripts.api.tsconst handler = async (request: Request): Promise<Response> => {
if (request.url.endsWith("/djs")) {
const supabaseUrl = "https://kodycvenourfbbbgphhl.supabase.co";
const supabaseKey = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImtvZHljdmVub3VyZmJiYmdwaGhsIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTY2NDY5MDg0NywiZXhwIjoxOTgwMjY2ODQ3fQ.kBf-ggVMtblzWPip1uYRomLKWrrmgSSLNaLW2ktB4a8";
const table = "Profile";
const response = await fetch(`${supabaseUrl}/rest/v1/${table}?select=*`, {
headers: {
apikey: supabaseKey,
Authorization: `Bearer ${supabaseKey}`,
},
});
if (!response.ok) {
console.error(new Error(`Fetch failed: ${response.status} ${response.statusText}`).stack);
return new Response("Failed to fetch djs", { status: 500 });
}
let data = await response.json();
data = data.map(dj => ({ ...dj, email: dj.email.toUpperCase() }));
console.log(`Fetched ${data.length} DJs from supabase`);
return new Response(JSON.stringify(data), {
headers: {
"content-type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
},
});
}
console.log('Request from...', request.origin);
return new Response("Hello from Deno server!", {
headers: {
"content-type": "text/plain",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
},
});
};
console.log("Deno server running on http://localhost:9001");
Deno.serve({ port: 9001 }, handler);
Playground.blocks.cursor-block.jsexport default class Cursor extends Block {
tagName = "cursor-block";
static defaultAttributes = {
class: "w-4 h-4",
};
render = `
<div>
<slot></slot>
</div>
`;
constructor() {
super();
}
connectedCallback() {
super.connectedCallback();
const player = localStorage.getItem("playerId");
const cursorUrl = this.getAttribute("cursor-url") || "/assets/img/cursor.png";
const grabbedUrl = this.getAttribute("grabbed-url") || "/assets/img/grabbed.png";
//console.log(player, this.getAttribute("player"));
if (player === this.getAttribute("player")) {
// Do nothing for current player
/* this.shadowRoot.querySelector("div").display = "none";
document.body.style.setProperty("--default-cursor", `url("${cursorUrl}"), default`);
document.body.style.setProperty("--grabbed-cursor", `url("${grabbedUrl}"), grabbing`);
document.body.style.cursor = "var(--default-cursor)";
document.addEventListener(
"mousemove",
(e) => {
const point = e.touches ? e.touches[0] : e;
const maxX = this.space.offsetWidth - this.shadowRoot.querySelector("div").offsetWidth;
const maxY = this.space.offsetWidth - this.shadowRoot.querySelector("div").offsetHeight;
const newX = Math.max(0, Math.min(point.pageX + Number(this.world.props["scroll-x"]), maxX));
const newY = Math.max(0, Math.min(point.pageY + Number(this.world.props["scroll-y"]), maxY));
this.shadowRoot.querySelector("div").style.transform = `translate(${newX}px, ${newY}px)`;
this.setAttribute("x", Math.round(newX));
this.setAttribute("y", Math.round(newY));
},
true
); */
} else {
this.classList.add(`bg-[url("${cursorUrl}")]`, "bg-no-repeat", "bg-center", "bg-contain");
}
}
}