mirror of
https://github.com/owncast/owncast.git
synced 2024-11-24 21:59:43 +03:00
Merge branch 'gek/webv2-merge' into develop
This commit is contained in:
commit
a51f831aa8
17 changed files with 90 additions and 178 deletions
4
.github/workflows/actions-lint.yml
vendored
4
.github/workflows/actions-lint.yml
vendored
|
@ -2,13 +2,9 @@ name: Lint
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- webv2
|
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/*'
|
- '.github/workflows/*'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
|
||||||
- webv2
|
|
||||||
paths:
|
paths:
|
||||||
- '.github/workflows/*'
|
- '.github/workflows/*'
|
||||||
|
|
||||||
|
|
4
.github/workflows/auto-comment-on-label.yaml
vendored
4
.github/workflows/auto-comment-on-label.yaml
vendored
|
@ -32,8 +32,8 @@ jobs:
|
||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
|
|
||||||
- Current web work is taking place in the [`webv2` branch](https://github.com/owncast/owncast/tree/webv2) and it is very much work in progress. Read the [README](https://github.com/owncast/owncast/blob/webv2/web/README.md) for this branch to get the web project running. But it's mostly just a `npm install` and `npm run dev`.
|
- Development takes place on the `develop` branch.
|
||||||
- We use Storybook for testing and developing React components. `npm run storybook`.
|
- We use Storybook for testing and developing React components. `npm run storybook`. A hosted version [is available for viewing](https://owncast.online/components).
|
||||||
- If you need to install the Go programming language to run the Owncast backend it's simple from [here](https://go.dev/dl/).
|
- If you need to install the Go programming language to run the Owncast backend it's simple from [here](https://go.dev/dl/).
|
||||||
- Active contributors get an Owncast t-shirt! Ask about it if you feel like you've been contributing and haven't yet been given one.
|
- Active contributors get an Owncast t-shirt! Ask about it if you feel like you've been contributing and haven't yet been given one.
|
||||||
|
|
||||||
|
|
4
.github/workflows/build-storybook.yml
vendored
4
.github/workflows/build-storybook.yml
vendored
|
@ -2,7 +2,7 @@ name: Build and Deploy Components+Style Guide
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
paths: ['web/stories/**', 'web/components/**', 'web/.storybook/**'] # Trigger the action only when files change in the folders defined here
|
paths: ['web/stories/**', 'web/components/**', 'web/.storybook/**'] # Trigger the action only when files change in the folders defined here
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -13,8 +13,6 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
ref: webv2 # Remove when webv2 gets merged into develop
|
|
||||||
|
|
||||||
- name: Install and Build
|
- name: Install and Build
|
||||||
run: | # Install npm packages and build the Storybook files
|
run: | # Install npm packages and build the Storybook files
|
||||||
|
|
1
.github/workflows/bundle-web.yml
vendored
1
.github/workflows/bundle-web.yml
vendored
|
@ -2,7 +2,6 @@ name: Build and bundle web app into Owncast
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
|
||||||
- develop
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- 'web/**'
|
- 'web/**'
|
||||||
|
|
1
.github/workflows/chromatic.yml
vendored
1
.github/workflows/chromatic.yml
vendored
|
@ -47,6 +47,5 @@ jobs:
|
||||||
# Chromatic GitHub Action options
|
# Chromatic GitHub Action options
|
||||||
with:
|
with:
|
||||||
workingDir: web
|
workingDir: web
|
||||||
autoAcceptChanges: webv2
|
|
||||||
projectToken: f47410569b62
|
projectToken: f47410569b62
|
||||||
onlyChanged: true
|
onlyChanged: true
|
||||||
|
|
4
.github/workflows/container-lint.yml
vendored
4
.github/workflows/container-lint.yml
vendored
|
@ -3,12 +3,12 @@ name: Lint
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
|
|
||||||
|
|
13
.github/workflows/container.yaml
vendored
13
.github/workflows/container.yaml
vendored
|
@ -8,10 +8,10 @@ on:
|
||||||
- cron: '0 2 * * *'
|
- cron: '0 2 * * *'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Earthly:
|
Earthly:
|
||||||
|
@ -42,15 +42,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
if: ${{ github.event_name == 'schedule' && env.GH_CR_PAT != null }}
|
|
||||||
env:
|
|
||||||
GH_CR_PAT: ${{ secrets.GH_CR_PAT }}
|
|
||||||
EARTHLY_BUILD_TAG: 'webv2'
|
|
||||||
EARTHLY_BUILD_BRANCH: 'webv2'
|
|
||||||
EARTHLY_PUSH: true
|
|
||||||
run: ./build/develop/container.sh
|
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
if: ${{ github.event_name == 'schedule' && env.GH_CR_PAT != null }}
|
if: ${{ github.event_name == 'schedule' && env.GH_CR_PAT != null }}
|
||||||
uses: nick-fields/retry@v2
|
uses: nick-fields/retry@v2
|
||||||
|
|
4
.github/workflows/shellcheck.yml
vendored
4
.github/workflows/shellcheck.yml
vendored
|
@ -3,12 +3,12 @@ name: Lint
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- '**.sh'
|
- '**.sh'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- webv2
|
- develop
|
||||||
paths:
|
paths:
|
||||||
- '**.sh'
|
- '**.sh'
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ set -e
|
||||||
# $EARTHLY_BUILD_TAG: tag for container image
|
# $EARTHLY_BUILD_TAG: tag for container image
|
||||||
|
|
||||||
EARTHLY_IMAGE_NAME="owncast"
|
EARTHLY_IMAGE_NAME="owncast"
|
||||||
BUILD_TAG=${EARTHLY_BUILD_TAG:-webv2}
|
BUILD_TAG=${EARTHLY_BUILD_TAG:-develop}
|
||||||
DATE=$(date +"%Y%m%d")
|
DATE=$(date +"%Y%m%d")
|
||||||
VERSION="${DATE}-${BUILD_TAG}"
|
VERSION="${DATE}-${BUILD_TAG}"
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ Specify the human readable version number in the `version` flag such as `v0.1.0`
|
||||||
|
|
||||||
Create and push the image to Docker Hub with a list of tags. You'll want to tag the image with both the new version number and `latest`.
|
Create and push the image to Docker Hub with a list of tags. You'll want to tag the image with both the new version number and `latest`.
|
||||||
|
|
||||||
**Run**: `earthly --push +docker-all --images="owncast/owncast:0.1.0 owncast/owncast:latest gabekangas/owncast:0.1.0 gabekangas/owncast:latest" --version="webv2"`
|
**Run**: `earthly --push +docker-all --images="owncast/owncast:0.1.0 owncast/owncast:latest gabekangas/owncast:0.1.0 gabekangas/owncast:latest" --version="v0.1.0"`
|
||||||
|
|
||||||
Omit `--push` if you don't want to push the image to Docker Hub and want to just build and test the image locally first.
|
Omit `--push` if you don't want to push the image to Docker Hub and want to just build and test the image locally first.
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
"config:base"
|
"config:base"
|
||||||
],
|
],
|
||||||
"baseBranches": [
|
"baseBranches": [
|
||||||
"develop",
|
"develop"
|
||||||
"webv2"
|
|
||||||
],
|
],
|
||||||
"timezone": "America/Los_Angeles",
|
"timezone": "America/Los_Angeles",
|
||||||
"lockFileMaintenance": {
|
"lockFileMaintenance": {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { ColorRow } from './Color';
|
||||||
|
|
||||||
# Default theme colors
|
# Default theme colors
|
||||||
|
|
||||||
These colors are assigned in our [color token](https://github.com/owncast/owncast/tree/webv2/web/style-definitions/tokens/color) files
|
These colors are assigned in our [color token](https://github.com/owncast/owncast/tree/develop/web/style-definitions/tokens/color) files
|
||||||
and get reflected here as they change. run `npm run build-styles` to regenerate.
|
and get reflected here as they change. run `npm run build-styles` to regenerate.
|
||||||
|
|
||||||
<Story
|
<Story
|
||||||
|
|
|
@ -6,11 +6,11 @@ import { Image, ImageRow } from './ImageAsset';
|
||||||
# Images
|
# Images
|
||||||
|
|
||||||
<ImageRow images={[
|
<ImageRow images={[
|
||||||
{src: "img/fediverse-black.png", name: "fediverse-black.png"},
|
{src: "/img/fediverse-black.png", name: "fediverse-black.png"},
|
||||||
{src: "img/fediverse-color.png", name: "fediverse-color.png"},
|
{src: "/img/fediverse-color.png", name: "fediverse-color.png"},
|
||||||
{src: "img/follow.svg", name: "follow.svg"},
|
{src: "/img/follow.svg", name: "follow.svg"},
|
||||||
{src: "img/indieauth.png", name: "indieauth.png"},
|
{src: "/img/indieauth.png", name: "indieauth.png"},
|
||||||
{src: "img/like.svg", name: "like.svg"},
|
{src: "/img/like.svg", name: "like.svg"},
|
||||||
{src: "img/repost.svg", name: "repost.svg"},
|
{src: "/img/repost.svg", name: "repost.svg"},
|
||||||
]}/>
|
]}/>
|
||||||
|
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
import { Meta } from '@storybook/addon-docs';
|
|
||||||
import { Typography } from 'antd';
|
|
||||||
|
|
||||||
<Meta title="Owncast/Documentation/Readme" />
|
|
||||||
|
|
||||||
<Typography.Title style={{ color: 'var(--primary-color)' }}>Owncast Web UI v2</Typography.Title>
|
|
||||||
|
|
||||||
Owncast is going through a complete rewrite of the web app frontend.
|
|
||||||
|
|
||||||
Visit the [UIv2 milestone](https://github.com/owncast/owncast/milestone/18) on GitHub to see the individual tasks for this project.
|
|
||||||
|
|
||||||
## Quick Links
|
|
||||||
|
|
||||||
- [Redesign project](https://github.com/owncast/owncast/milestone/18)
|
|
||||||
- [Currently defined colors](/story/owncast-style-guide-colors--page)
|
|
||||||
- [Owncast Frontend Chat](https://owncast.rocket.chat/group/frontend-dev)
|
|
||||||
|
|
||||||
## Why?
|
|
||||||
|
|
||||||
- Moving to a full React Component workflow allows the project to be more productive and build features faster.
|
|
||||||
- Share code between the web frontend UI and the existing admin.
|
|
||||||
- Address feedback from users.
|
|
||||||
- Better accessibility.
|
|
||||||
- Better mobile experience.
|
|
||||||
- Standardize styling across the project by using a single design language and style guide.
|
|
||||||
- Allows more people to contribute to the project if we use popular frameworks.
|
|
||||||
|
|
||||||
## What
|
|
||||||
|
|
||||||
- [Next.js](https://nextjs.org/)
|
|
||||||
- [React](https://reactjs.org/)
|
|
||||||
- [Ant Design](https://ant.design/)
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Find a component that hasn't yet been worked on by looking through the [UIv2 milestone](https://github.com/owncast/owncast/milestone/18)
|
|
||||||
and the sidebar of components to the left.
|
|
||||||
1. See if you can have an example of this functionality in action via the [Owncast Demo Server](https://watch.owncast.online) or [Owncast Nightly Build](https://nightly.owncast.online) so you know how it's supposed to work if it's interactive.
|
|
||||||
1. Visit the `Docs` tab to read any specific documentation that may have been written about how this component works.
|
|
||||||
1. Go to the `Canvas` tab of the component you selected and see if there's a Design attached to it.
|
|
||||||
1. If there is a design, then that's a starting point you can use to start building out the component.
|
|
||||||
1. If there isn't, then visit the [Owncast Demo Server](https://watch.owncast.online), the [Owncast Nightly Build](https://nightly.owncast.online), or the proposed [v2 design](https://www.figma.com/proto/B6ICOn1J3dyYeoZM5kPM2A/Owncast---Review?node-id=643%3A646&scaling=min-zoom&page-id=643%3A17&starting-point-node-id=643%3A44) for some ways to start.
|
|
||||||
1. If no design exists, then you can ask around the Owncast chat for help, for come up with your own ideas!
|
|
||||||
1. No designs are stuck in stone, and we're using this as an opportunity to level up the UI of Owncast, so all ideas are welcome.
|
|
||||||
|
|
||||||
## How?
|
|
||||||
|
|
||||||
This rewrite is a large project, but like anything else, breaking it into pieces and working on one thing at a time will eventually get us to the finish line.
|
|
||||||
And that's what this interface lets us do. On this page we see all the different components still needing to be worked on, and have a place to document the functionality of these pieces.
|
|
||||||
|
|
||||||
## What about the Admin?
|
|
||||||
|
|
||||||
The admin has always been a Next+React+Ant project, so the goal is to touch that as little as possible except where needed to share code and styles.
|
|
||||||
|
|
||||||
## What is this page?
|
|
||||||
|
|
||||||
This is called [_Storybook_](https://storybook.js.org/docs/react/get-started/introduction).
|
|
||||||
Storybook is a tool for UI development. It makes development faster and easier by isolating components.
|
|
||||||
This allows you to work on one component at a time. You can develop entire UIs without needing to start
|
|
||||||
up a complex dev stack, force certain data into your database, or navigate around your application.
|
|
||||||
|
|
||||||
For example a button may have a disabled state that requires a specific scenario to take place in real-world use,
|
|
||||||
but here we you can just toggle the state to verify things are working as expected.
|
|
||||||
|
|
||||||
This means [new components should have a corresponding story added](https://storybook.js.org/docs/react/get-started/whats-a-story) to make it easier to maintain the project.
|
|
||||||
|
|
||||||
For more details about building React components read [this document](https://github.com/owncast/owncast/blob/webv2/web/components/_COMPONENT_HOW_TO.md) with specifics.
|
|
||||||
|
|
||||||
<img src="https://user-images.githubusercontent.com/9563255/187112334-e6c73bad-72df-42fc-9ee2-8d36ba615275.png"/>
|
|
|
@ -6,15 +6,14 @@ import { Image, ImageRow } from './ImageAsset';
|
||||||
# Logos & Graphics
|
# Logos & Graphics
|
||||||
|
|
||||||
<ImageRow images={[
|
<ImageRow images={[
|
||||||
{src: "project/header.png", name: "header.png"},
|
{src: "/project/header.png", name: "header.png"},
|
||||||
{src: "project/kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png", name: "kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png"},
|
{src: "/project/kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png", name: "kiss-cut-stickers-5.5x5.5-default-60874a6c11849.png"},
|
||||||
{src: "project/logo-glare-outlined.png", name: "logo-glare-outlined.png"},
|
{src: "/project/logo-glare-outlined.png", name: "logo-glare-outlined.png"},
|
||||||
{src: "project/logo-glare-vector.svg", name: "logo-glare-vector.svg"},
|
{src: "/project/logo-glare-vector.svg", name: "logo-glare-vector.svg"},
|
||||||
{src: "project/logo-noglare-vector.svg", name: "logo-noglare-vector.svg"},
|
{src: "/project/logo-noglare-vector.svg", name: "logo-noglare-vector.svg"},
|
||||||
{src: "project/logo-translucent-grey.svg", name: "logo-translucent-grey.svg"},
|
{src: "/project/logo-translucent-grey.svg", name: "logo-translucent-grey.svg"},
|
||||||
{src: "project/logo-white.svg", name: "logo-white.svg"},
|
{src: "/project/logo-white.svg", name: "logo-white.svg"},
|
||||||
{src: "project/owncast-background.png", name: "owncast-background.png"},
|
{src: "/project/owncast-background.png", name: "owncast-background.png"},
|
||||||
{src: "project/owncast-browser-mobile.png", name: "owncast-browser-mobile.png"},
|
{src: "/project/owncast-browser-mobile.png", name: "owncast-browser-mobile.png"},
|
||||||
{src: "project/sticker-bigtech-alt.png", name: "sticker-bigtech-alt.png"},
|
|
||||||
]}/>
|
]}/>
|
||||||
|
|
||||||
|
|
|
@ -6,36 +6,36 @@ import { Image, ImageRow } from './ImageAsset';
|
||||||
# Social Platform Images
|
# Social Platform Images
|
||||||
|
|
||||||
<ImageRow images={[
|
<ImageRow images={[
|
||||||
{src: "img/platformlogos/bandcamp.svg", name: "bandcamp.svg"},
|
{src: "/img/platformlogos/bandcamp.svg", name: "bandcamp.svg"},
|
||||||
{src: "img/platformlogos/default.svg", name: "default.svg"},
|
{src: "/img/platformlogos/default.svg", name: "default.svg"},
|
||||||
{src: "img/platformlogos/discord.svg", name: "discord.svg"},
|
{src: "/img/platformlogos/discord.svg", name: "discord.svg"},
|
||||||
{src: "img/platformlogos/donate.svg", name: "donate.svg"},
|
{src: "/img/platformlogos/donate.svg", name: "donate.svg"},
|
||||||
{src: "img/platformlogos/facebook.svg", name: "facebook.svg"},
|
{src: "/img/platformlogos/facebook.svg", name: "facebook.svg"},
|
||||||
{src: "img/platformlogos/fediverse.svg", name: "fediverse.svg"},
|
{src: "/img/platformlogos/fediverse.svg", name: "fediverse.svg"},
|
||||||
{src: "img/platformlogos/follow.svg", name: "follow.svg"},
|
{src: "/img/platformlogos/follow.svg", name: "follow.svg"},
|
||||||
{src: "img/platformlogos/github.svg", name: "github.svg"},
|
{src: "/img/platformlogos/github.svg", name: "github.svg"},
|
||||||
{src: "img/platformlogos/gitlab.svg", name: "gitlab.svg"},
|
{src: "/img/platformlogos/gitlab.svg", name: "gitlab.svg"},
|
||||||
{src: "img/platformlogos/google.svg", name: "google.svg"},
|
{src: "/img/platformlogos/google.svg", name: "google.svg"},
|
||||||
{src: "img/platformlogos/instagram.svg", name: "instagram.svg"},
|
{src: "/img/platformlogos/instagram.svg", name: "instagram.svg"},
|
||||||
{src: "img/platformlogos/keyoxide.png", name: "keyoxide.png"},
|
{src: "/img/platformlogos/keyoxide.png", name: "keyoxide.png"},
|
||||||
{src: "img/platformlogos/ko-fi.svg", name: "ko-fi.svg"},
|
{src: "/img/platformlogos/ko-fi.svg", name: "ko-fi.svg"},
|
||||||
{src: "img/platformlogos/lbry.svg", name: "lbry.svg"},
|
{src: "/img/platformlogos/lbry.svg", name: "lbry.svg"},
|
||||||
{src: "img/platformlogos/liberapay.svg", name: "liberapay.svg"},
|
{src: "/img/platformlogos/liberapay.svg", name: "liberapay.svg"},
|
||||||
{src: "img/platformlogos/link.svg", name: "link.svg"},
|
{src: "/img/platformlogos/link.svg", name: "link.svg"},
|
||||||
{src: "img/platformlogos/linkedin.svg", name: "linkedin.svg"},
|
{src: "/img/platformlogos/linkedin.svg", name: "linkedin.svg"},
|
||||||
{src: "img/platformlogos/mastodon.svg", name: "mastodon.svg"},
|
{src: "/img/platformlogos/mastodon.svg", name: "mastodon.svg"},
|
||||||
{src: "img/platformlogos/matrix.svg", name: "matrix.svg"},
|
{src: "/img/platformlogos/matrix.svg", name: "matrix.svg"},
|
||||||
{src: "img/platformlogos/odysee.svg", name: "odysee.svg"},
|
{src: "/img/platformlogos/odysee.svg", name: "odysee.svg"},
|
||||||
{src: "img/platformlogos/patreon.svg", name: "patreon.svg"},
|
{src: "/img/platformlogos/patreon.svg", name: "patreon.svg"},
|
||||||
{src: "img/platformlogos/paypal.svg", name: "paypal.svg"},
|
{src: "/img/platformlogos/paypal.svg", name: "paypal.svg"},
|
||||||
{src: "img/platformlogos/snapchat.svg", name: "snapchat.svg"},
|
{src: "/img/platformlogos/snapchat.svg", name: "snapchat.svg"},
|
||||||
{src: "img/platformlogos/soundcloud.svg", name: "soundcloud.svg"},
|
{src: "/img/platformlogos/soundcloud.svg", name: "soundcloud.svg"},
|
||||||
{src: "img/platformlogos/spotify.svg", name: "spotify.svg"},
|
{src: "/img/platformlogos/spotify.svg", name: "spotify.svg"},
|
||||||
{src: "img/platformlogos/steam.svg", name: "steam.svg"},
|
{src: "/img/platformlogos/steam.svg", name: "steam.svg"},
|
||||||
{src: "img/platformlogos/tiktok.svg", name: "tiktok.svg"},
|
{src: "/img/platformlogos/tiktok.svg", name: "tiktok.svg"},
|
||||||
{src: "img/platformlogos/twitch.svg", name: "twitch.svg"},
|
{src: "/img/platformlogos/twitch.svg", name: "twitch.svg"},
|
||||||
{src: "img/platformlogos/twitter.svg", name: "twitter.svg"},
|
{src: "/img/platformlogos/twitter.svg", name: "twitter.svg"},
|
||||||
{src: "img/platformlogos/xmpp.svg", name: "xmpp.svg"},
|
{src: "/img/platformlogos/xmpp.svg", name: "xmpp.svg"},
|
||||||
{src: "img/platformlogos/youtube.svg", name: "youtube.svg"},
|
{src: "/img/platformlogos/youtube.svg", name: "youtube.svg"},
|
||||||
]}/>
|
]}/>
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,18 @@ import { Image, ImageRow } from './ImageAsset';
|
||||||
# T-shirt
|
# T-shirt
|
||||||
|
|
||||||
<ImageRow images={[
|
<ImageRow images={[
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde52297.png"},
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde523ae.png"},
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png", name: "all-over-print-mens-crew-neck-t-shirt-white-back-60873dde524ca.png"},
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde51eb3.png"},
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png", name: "all-over-print-mens-crew-neck-t-shirt-white-front-60873dde52064.png"},
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png", name: "all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png", name: "all-over-print-mens-crew-neck-t-shirt-white-left-60873dde525e2.png"},
|
||||||
{src: "tshirt/all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png", name: "all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png"},
|
{src: "/tshirt/all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png", name: "all-over-print-mens-crew-neck-t-shirt-white-right-60873dde52184.png"},
|
||||||
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png"},
|
{src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62999.png"},
|
||||||
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png"},
|
{src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png", name: "all-over-print-womens-crew-neck-t-shirt-white-back-6087418b62aa4.png"},
|
||||||
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png"},
|
{src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b626d5.png"},
|
||||||
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png"},
|
{src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png", name: "all-over-print-womens-crew-neck-t-shirt-white-front-6087418b62878.png"},
|
||||||
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png", name: "all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png"},
|
{src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png", name: "all-over-print-womens-crew-neck-t-shirt-white-left-6087418b62b91.png"},
|
||||||
{src: "tshirt/all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png", name: "all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png"},
|
{src: "/tshirt/all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png", name: "all-over-print-womens-crew-neck-t-shirt-white-right-6087418b62c88.png"},
|
||||||
]}/>
|
]}/>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue