This commit is contained in:
Eduard Urbach 2017-10-09 15:47:40 +02:00
parent be3dede5a9
commit 6e4897f435
21 changed files with 236 additions and 75 deletions

View File

@ -83,12 +83,9 @@ func configure(app *aero.Application) *aero.Application {
app.Ajax("/forum/:tag", forum.Get) app.Ajax("/forum/:tag", forum.Get)
app.Ajax("/thread/:id", threads.Get) app.Ajax("/thread/:id", threads.Get)
app.Ajax("/post/:id", posts.Get) app.Ajax("/post/:id", posts.Get)
app.Ajax("/soundtrack/:id", soundtrack.Get)
app.Ajax("/character/:id", character.Get) app.Ajax("/character/:id", character.Get)
app.Ajax("/new/thread", newthread.Get) app.Ajax("/new/thread", newthread.Get)
app.Ajax("/new/soundtrack", newsoundtrack.Get)
app.Ajax("/settings", settings.Get) app.Ajax("/settings", settings.Get)
app.Ajax("/soundtracks", soundtracks.Get)
app.Ajax("/artworks", artworks.Get) app.Ajax("/artworks", artworks.Get)
app.Ajax("/amvs", amvs.Get) app.Ajax("/amvs", amvs.Get)
app.Ajax("/users", users.Active) app.Ajax("/users", users.Active)
@ -99,6 +96,12 @@ func configure(app *aero.Application) *aero.Application {
app.Ajax("/statistics/anime", statistics.Anime) app.Ajax("/statistics/anime", statistics.Anime)
app.Ajax("/login", login.Get) app.Ajax("/login", login.Get)
// Soundtracks
app.Ajax("/soundtracks", soundtracks.Get)
app.Ajax("/new/soundtrack", newsoundtrack.Get)
app.Ajax("/soundtrack/:id", soundtrack.Get)
app.Ajax("/soundtrack/:id/edit", soundtrack.Edit)
// User profiles // User profiles
app.Ajax("/user", user.Get) app.Ajax("/user", user.Get)
app.Ajax("/user/:nick", profile.Get) app.Ajax("/user/:nick", profile.Get)

View File

@ -1,19 +1,32 @@
component InputText(id string, value string, label string, placeholder string) component InputText(id string, value string, label string, placeholder string)
.widget-input .widget-section
label(for=id)= label + ":" label(for=id)= label + ":"
input.widget-element.action(id=id, data-field=id, type="text", value=value, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change") input.widget-ui-element.action(id=id, data-field=id, type="text", value=value, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")
component InputTextArea(id string, value string, label string, placeholder string) component InputTextArea(id string, value string, label string, placeholder string)
.widget-input .widget-section
label(for=id)= label + ":" label(for=id)= label + ":"
textarea.widget-element.action(id=id, data-field=id, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")= value textarea.widget-ui-element.action(id=id, data-field=id, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")= value
component InputNumber(id string, value float64, label string, placeholder string, min string, max string, step string) component InputNumber(id string, value float64, label string, placeholder string, min string, max string, step string)
.widget-input .widget-section
label(for=id)= label + ":" label(for=id)= label + ":"
input.widget-element.action(id=id, data-field=id, type="number", value=value, min=min, max=max, step=step, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change") input.widget-ui-element.action(id=id, data-field=id, type="number", value=value, min=min, max=max, step=step, placeholder=placeholder, title=placeholder, data-action="save", data-trigger="change")
component InputSelection(id string, value string, label string, placeholder string, values []string) component InputSelection(id string, value string, label string, placeholder string, values []string)
.widget-input .widget-section
label(for=id)= label + ":" label(for=id)= label + ":"
select.widget-element.action(id=id, data-field=id, value=value, title=placeholder, data-action="save", data-trigger="change") select.widget-ui-element.action(id=id, data-field=id, value=value, title=placeholder, data-action="save", data-trigger="change")
component InputTags(id string, value []string, label string)
.widget-section
label(for=id)= label + ":"
.tags(id=id)
each tag in value
.tag
span.tag-title= tag
.tag-remove.action(data-action="removeTag", data-trigger="click", data-tag=tag) x
button.tag-add
RawIcon("plus")

View File

@ -7,9 +7,9 @@ component AnimeListItem(viewUser *arn.User, item *arn.AnimeListItem, anime *arn.
.anime-list-item-episodes-edit .anime-list-item-episodes-edit
InputNumber("Episodes", float64(item.Episodes), "Episodes", "Number of episodes you watched", "0", arn.EpisodeCountMax(anime.EpisodeCount), "1") InputNumber("Episodes", float64(item.Episodes), "Episodes", "Number of episodes you watched", "0", arn.EpisodeCountMax(anime.EpisodeCount), "1")
.widget-input.anime-list-item-status-edit .widget-section.anime-list-item-status-edit
label(for="Status") Status: label(for="Status") Status:
select.widget-element.action(id="Status", data-field="Status", value=item.Status, data-action="save", data-trigger="change") select.widget-ui-element.action(id="Status", data-field="Status", value=item.Status, data-action="save", data-trigger="change")
option(value=arn.AnimeListStatusWatching) Watching option(value=arn.AnimeListStatusWatching) Watching
option(value=arn.AnimeListStatusCompleted) Completed option(value=arn.AnimeListStatusCompleted) Completed
option(value=arn.AnimeListStatusPlanned) Plan to watch option(value=arn.AnimeListStatusPlanned) Plan to watch

View File

@ -14,5 +14,5 @@
horizontal-wrap horizontal-wrap
justify-content space-between justify-content space-between
width 100% width 100%
.widget-input .widget-section
max-width 20% max-width 20%

View File

@ -7,16 +7,16 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
for i := 0; i <= 4; i++ for i := 0; i <= 4; i++
if i < len(schedule) if i < len(schedule)
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
a.schedule-item-link.ajax(href=schedule[i].Anime.Link()) a.schedule-item-link.ajax(href=schedule[i].Anime.Link())
Icon("calendar-o") Icon("calendar-o")
.schedule-item-title= schedule[i].Anime.Title.Canonical .schedule-item-title= schedule[i].Anime.Title.Canonical
.spacer .spacer
.schedule-item-date.utc-airing-date(data-start-date=schedule[i].Episode.AiringDate.Start, data-end-date=schedule[i].Episode.AiringDate.End, data-episode-number=schedule[i].Episode.Number) .schedule-item-date.utc-airing-date(data-start-date=schedule[i].Episode.AiringDate.Start, data-end-date=schedule[i].Episode.AiringDate.End, data-episode-number=schedule[i].Episode.Number)
else else
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("calendar-o") Icon("calendar-o")
span ... span ...
@ -24,8 +24,8 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
h3.widget-title Forums h3.widget-title Forums
each post in posts each post in posts
a.widget-element.ajax(href=post.Thread().Link()) a.widget-ui-element.ajax(href=post.Thread().Link())
.widget-element-text .widget-ui-element-text
Icon(arn.GetForumIcon(post.Thread().Tags[0])) Icon(arn.GetForumIcon(post.Thread().Tags[0]))
span= post.Thread().Title span= post.Thread().Title
@ -33,8 +33,8 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
h3.widget-title Artworks h3.widget-title Artworks
for i := 1; i <= 5; i++ for i := 1; i <= 5; i++
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("paint-brush") Icon("paint-brush")
span ... span ...
@ -43,13 +43,13 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
for i := 0; i <= 4; i++ for i := 0; i <= 4; i++
if i < len(soundTracks) if i < len(soundTracks)
a.widget-element.ajax(href=soundTracks[i].Link()) a.widget-ui-element.ajax(href=soundTracks[i].Link())
.widget-element-text .widget-ui-element-text
Icon("music") Icon("music")
span(title=soundTracks[i].Media[0].Title)= soundTracks[i].Anime()[0].Title.Canonical span(title=soundTracks[i].Media[0].Title)= soundTracks[i].Anime()[0].Title.Canonical
else else
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("music") Icon("music")
span ... span ...
@ -57,8 +57,8 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
h3.widget-title AMVs h3.widget-title AMVs
for i := 1; i <= 5; i++ for i := 1; i <= 5; i++
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("video-camera") Icon("video-camera")
span ... span ...
@ -66,8 +66,8 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
h3.widget-title Reviews h3.widget-title Reviews
for i := 1; i <= 5; i++ for i := 1; i <= 5; i++
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("book") Icon("book")
span ... span ...
@ -75,8 +75,8 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
h3.widget-title Groups h3.widget-title Groups
for i := 1; i <= 5; i++ for i := 1; i <= 5; i++
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("group") Icon("group")
span ... span ...
@ -85,13 +85,13 @@ component Dashboard(schedule []*arn.UpcomingEpisode, posts []arn.Postable, sound
for i := 0; i <= 4; i++ for i := 0; i <= 4; i++
if i < len(following) if i < len(following)
a.widget-element.ajax(href="/+" + following[i].Nick) a.widget-ui-element.ajax(href="/+" + following[i].Nick)
.widget-element-text .widget-ui-element-text
Icon("address-card") Icon("address-card")
span= following[i].Nick span= following[i].Nick
else else
.widget-element .widget-ui-element
.widget-element-text .widget-ui-element-text
Icon("address-card") Icon("address-card")
span ... span ...

View File

@ -2,21 +2,21 @@ component ImportLists(user *arn.User)
if user.Accounts.AniList.Nick != "" if user.Accounts.AniList.Nick != ""
label AniList: label AniList:
.widget-input .widget-section
a.button.mountable.ajax(href="/import/anilist/animelist") a.button.mountable.ajax(href="/import/anilist/animelist")
Icon("download") Icon("download")
span Import AniList span Import AniList
if user.Accounts.Kitsu.Nick != "" if user.Accounts.Kitsu.Nick != ""
label Kitsu: label Kitsu:
.widget-input .widget-section
a.button.mountable.ajax(href="/import/kitsu/animelist") a.button.mountable.ajax(href="/import/kitsu/animelist")
Icon("download") Icon("download")
span Import Kitsu span Import Kitsu
if user.Accounts.MyAnimeList.Nick != "" if user.Accounts.MyAnimeList.Nick != ""
label MyAnimeList: label MyAnimeList:
.widget-input .widget-section
a.button.mountable.ajax(href="/import/myanimelist/animelist") a.button.mountable.ajax(href="/import/myanimelist/animelist")
Icon("download") Icon("download")
span Import MyAnimeList span Import MyAnimeList

View File

@ -3,21 +3,21 @@ component NewSoundTrack(user *arn.User)
.widget .widget
h1 New soundtrack h1 New soundtrack
.widget-input .widget-section
label(for="soundcloud-link") Soundcloud link: label(for="soundcloud-link") Soundcloud link:
input#soundcloud-link.widget-element(type="text", placeholder="https://soundcloud.com/abc/123") input#soundcloud-link.widget-ui-element(type="text", placeholder="https://soundcloud.com/abc/123")
.widget-input .widget-section
label(for="youtube-link") Youtube link: label(for="youtube-link") Youtube link:
input#youtube-link.widget-element(type="text", placeholder="https://www.youtube.com/watch?v=123") input#youtube-link.widget-ui-element(type="text", placeholder="https://www.youtube.com/watch?v=123")
.widget-input .widget-section
label(for="anime-link") Anime link: label(for="anime-link") Anime link:
input#anime-link.widget-element(type="text", placeholder="https://notify.moe/anime/123") input#anime-link.widget-ui-element(type="text", placeholder="https://notify.moe/anime/123")
.widget-input .widget-section
label(for="osu-link") Osu beatmap (optional): label(for="osu-link") Osu beatmap (optional):
input#osu-link.widget-element(type="text", placeholder="https://osu.ppy.sh/s/123") input#osu-link.widget-ui-element(type="text", placeholder="https://osu.ppy.sh/s/123")
.buttons .buttons
button.action(data-action="createSoundTrack", data-trigger="click") button.action(data-action="createSoundTrack", data-trigger="click")

View File

@ -3,11 +3,11 @@ component NewThread(user *arn.User)
.widget-form .widget-form
.widget .widget
input#title.widget-element(type="text", placeholder="Title") input#title.widget-ui-element(type="text", placeholder="Title")
textarea#text.widget-element(placeholder="Content") textarea#text.widget-ui-element(placeholder="Content")
select#tag.widget-element(value="general") select#tag.widget-ui-element(value="general")
option(value="general") General option(value="general") General
option(value="news") News option(value="news") News
option(value="anime") Anime option(value="anime") Anime

View File

@ -26,19 +26,19 @@ component Settings(user *arn.User)
Icon("bell") Icon("bell")
span Notifications span Notifications
#enable-notifications.widget-input #enable-notifications.widget-section
label Enable: label Enable:
button.action(data-action="enableNotifications", data-trigger="click") button.action(data-action="enableNotifications", data-trigger="click")
Icon("toggle-off") Icon("toggle-off")
span Enable notifications span Enable notifications
#disable-notifications.widget-input #disable-notifications.widget-section
label Disable: label Disable:
button.action(data-action="disableNotifications", data-trigger="click") button.action(data-action="disableNotifications", data-trigger="click")
Icon("toggle-on") Icon("toggle-on")
span Disable notifications span Disable notifications
#test-notification.widget-input #test-notification.widget-section
label Test: label Test:
button.action(data-action="testNotification", data-trigger="click") button.action(data-action="testNotification", data-trigger="click")
Icon("paper-plane") Icon("paper-plane")
@ -49,7 +49,7 @@ component Settings(user *arn.User)
Icon("user-plus") Icon("user-plus")
span Connect span Connect
.widget-input.social-account .widget-section.social-account
label(for="google") Google: label(for="google") Google:
a#google.button.social-account-button(href="/auth/google") a#google.button.social-account-button(href="/auth/google")
@ -60,7 +60,7 @@ component Settings(user *arn.User)
Icon("circle-o") Icon("circle-o")
span Not connected span Not connected
.widget-input.social-account .widget-section.social-account
label(for="facebook") Facebook: label(for="facebook") Facebook:
a#facebook.button.social-account-button(href="/auth/facebook") a#facebook.button.social-account-button(href="/auth/facebook")
@ -84,7 +84,7 @@ component Settings(user *arn.User)
Icon("upload") Icon("upload")
span Export span Export
.widget-input .widget-section
label JSON: label JSON:
a.button(href="/api/animelist/" + user.ID) a.button(href="/api/animelist/" + user.ID)
Icon("upload") Icon("upload")
@ -95,19 +95,19 @@ component Settings(user *arn.User)
Icon("puzzle-piece") Icon("puzzle-piece")
span Apps span Apps
.widget-input .widget-section
label Chrome Extension: label Chrome Extension:
button.action(data-action="installExtension", data-trigger="click") button.action(data-action="installExtension", data-trigger="click")
Icon("chrome") Icon("chrome")
span Get the Chrome Extension span Get the Chrome Extension
.widget-input .widget-section
label Desktop App: label Desktop App:
button.action(data-action="installApp", data-trigger="click") button.action(data-action="installApp", data-trigger="click")
Icon("desktop") Icon("desktop")
span Get the Desktop App span Get the Desktop App
.widget-input .widget-section
label Android App: label Android App:
a.button(href="https://www.youtube.com/watch?v=opyt4cw0ep8", target="_blank", rel="noopener") a.button(href="https://www.youtube.com/watch?v=opyt4cw0ep8", target="_blank", rel="noopener")
Icon("android") Icon("android")
@ -118,9 +118,9 @@ component Settings(user *arn.User)
Icon("picture-o") Icon("picture-o")
span Avatar span Avatar
.widget-input .widget-section
label(for="Avatar.Source") Source: label(for="Avatar.Source") Source:
select.widget-element.action(id="Avatar.Source", data-field="Avatar.Source", value=user.Settings().Avatar.Source, data-action="save", data-trigger="change") select.widget-ui-element.action(id="Avatar.Source", data-field="Avatar.Source", value=user.Settings().Avatar.Source, data-action="save", data-trigger="change")
option(value="") Automatic option(value="") Automatic
option(value="Gravatar") Gravatar option(value="Gravatar") Gravatar
option(value="URL") Link option(value="URL") Link
@ -143,7 +143,7 @@ component Settings(user *arn.User)
span PRO span PRO
if user.IsPro() if user.IsPro()
.widget-input .widget-section
label label
span Your PRO account expires in span Your PRO account expires in
span.utc-date(data-date=user.ProExpires) span.utc-date(data-date=user.ProExpires)
@ -152,7 +152,7 @@ component Settings(user *arn.User)
Icon("star") Icon("star")
span Extend PRO account duration span Extend PRO account duration
else else
.widget-input .widget-section
label Would you like to support the site development? label Would you like to support the site development?
a.button.ajax(href="/shop") a.button.ajax(href="/shop")
Icon("star") Icon("star")

View File

@ -1,4 +1,4 @@
.widget-input .widget-section
button, button,
.button .button
margin-bottom 1rem margin-bottom 1rem

74
pages/soundtrack/edit.go Normal file
View File

@ -0,0 +1,74 @@
package soundtrack
import (
"bytes"
"net/http"
"reflect"
"strings"
"github.com/animenotifier/notify.moe/components"
"github.com/aerogo/aero"
"github.com/animenotifier/arn"
)
// Edit track.
func Edit(ctx *aero.Context) string {
id := ctx.Get("id")
track, err := arn.GetSoundTrack(id)
if err != nil {
return ctx.Error(http.StatusNotFound, "Track not found", err)
}
ctx.Data = &arn.OpenGraph{
Tags: map[string]string{
"og:title": track.Media[0].Title,
"og:image": track.MainAnime().Image.Large,
"og:url": "https://" + ctx.App.Config.Domain + track.Link(),
"og:site_name": "notify.moe",
"og:type": "music.song",
},
}
return ctx.HTML(EditForm(track, "Edit soundtrack"))
}
// EditForm ...
func EditForm(obj interface{}, title string) string {
t := reflect.TypeOf(obj).Elem()
v := reflect.ValueOf(obj).Elem()
lowerCaseTypeName := strings.ToLower(t.Name())
id := reflect.Indirect(v.FieldByName("ID"))
var b bytes.Buffer
b.WriteString(`<div class="widget-form">`)
b.WriteString(`<div class="widget" data-api="/api/` + lowerCaseTypeName + `/` + id.String() + `">`)
b.WriteString(`<h1>`)
b.WriteString(title)
b.WriteString(`</h1>`)
// Fields
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.Anonymous || field.Tag.Get("editable") != "true" {
continue
}
fieldValue := reflect.Indirect(v.FieldByName(field.Name))
switch field.Type.String() {
case "string":
b.WriteString(components.InputText(field.Name, fieldValue.String(), field.Name, ""))
case "[]string":
b.WriteString(components.InputTags(field.Name, fieldValue.Interface().([]string), field.Name))
default:
panic("No edit form implementation for " + field.Name + " with type " + field.Type.String())
}
}
b.WriteString("</div>")
b.WriteString("</div>")
return b.String()
}

View File

@ -20,7 +20,7 @@ func Get(ctx *aero.Context) string {
ctx.Data = &arn.OpenGraph{ ctx.Data = &arn.OpenGraph{
Tags: map[string]string{ Tags: map[string]string{
"og:title": track.Media[0].Title, "og:title": track.Media[0].Title,
"og:image": track.Anime()[0].Image.Large, "og:image": track.MainAnime().Image.Large,
"og:url": "https://" + ctx.App.Config.Domain + track.Link(), "og:url": "https://" + ctx.App.Config.Domain + track.Link(),
"og:site_name": "notify.moe", "og:site_name": "notify.moe",
"og:type": "music.song", "og:type": "music.song",

View File

@ -1,5 +1,8 @@
component Track(track *arn.SoundTrack) component Track(track *arn.SoundTrack)
h1= track.Media[0].Title h1= track.Title
.sound-tracks .sound-tracks
SoundTrackAllMedia(track) SoundTrackAllMedia(track)
p
a.ajax(href=track.Link() + "/edit") Edit

View File

@ -10,9 +10,11 @@ import (
const maxTracks = 9 const maxTracks = 9
// Get renders the music page. // Get renders the soundtracks page.
func Get(ctx *aero.Context) string { func Get(ctx *aero.Context) string {
tracks, err := arn.AllSoundTracks() tracks, err := arn.FilterSoundTracks(func(track *arn.SoundTrack) bool {
return !track.IsDraft
})
if err != nil { if err != nil {
return ctx.Error(http.StatusInternalServerError, "Error fetching soundtracks", err) return ctx.Error(http.StatusInternalServerError, "Error fetching soundtracks", err)
@ -24,5 +26,5 @@ func Get(ctx *aero.Context) string {
tracks = tracks[:maxTracks] tracks = tracks[:maxTracks]
} }
return ctx.HTML(components.Music(tracks)) return ctx.HTML(components.SoundTracks(tracks))
} }

View File

@ -1,4 +1,4 @@
component Music(tracks []*arn.SoundTrack) component SoundTracks(tracks []*arn.SoundTrack)
h1 Soundtracks h1 Soundtracks
.music-buttons .music-buttons

View File

@ -0,0 +1,22 @@
package main
import (
"fmt"
"github.com/animenotifier/arn"
"github.com/fatih/color"
)
func main() {
color.Yellow("Addind draft indices")
// Iterate over the stream
for user := range arn.MustStreamUsers() {
fmt.Println(user.Nick)
draftIndex := arn.NewDraftIndex(user.ID)
arn.PanicOnError(draftIndex.Save())
}
color.Green("Finished.")
}

View File

@ -34,7 +34,7 @@ func main() {
fmt.Println(user.Nick) fmt.Println(user.Nick)
inventory := arn.NewInventory(user.ID) inventory := arn.NewInventory(user.ID)
err = arn.DB.Set("Inventory", inventory.UserID, inventory) err = inventory.Save()
if err != nil { if err != nil {
color.Red(err.Error()) color.Red(err.Error())

View File

@ -0,0 +1,11 @@
package main
import (
"github.com/animenotifier/arn"
)
func main() {
for track := range arn.MustStreamSoundTracks() {
arn.PanicOnError(track.Save())
}
}

View File

@ -365,6 +365,15 @@ export function buyItem(arn: AnimeNotifier, button: HTMLElement) {
.then(() => arn.loading(false)) .then(() => arn.loading(false))
} }
// Remove tag
export function removeTag(arn: AnimeNotifier, element: HTMLElement) {
let tag = element.dataset.tag
// arn.loading(true)
alert("Remove " + tag)
}
// Chrome extension installation // Chrome extension installation
export function installExtension(arn: AnimeNotifier, button: HTMLElement) { export function installExtension(arn: AnimeNotifier, button: HTMLElement) {
let browser: any = window["chrome"] let browser: any = window["chrome"]

24
styles/tags.scarlet Normal file
View File

@ -0,0 +1,24 @@
.tags
horizontal-wrap
.tag
ui-element
padding 0.4rem 0.8rem
margin 0.4rem
.tag-input
horizontal
button
margin-left 0.8rem
.tag-remove
display inline-block
margin-left 0.4rem
opacity 0.5
:hover
cursor pointer
.tag-add
margin 0.4rem !important

View File

@ -20,7 +20,7 @@
margin-bottom 1rem margin-bottom 1rem
overflow hidden overflow hidden
.widget-element .widget-ui-element
vertical-wrap vertical-wrap
ui-element ui-element
transition border transition-speed ease, background transition-speed ease, transform transition-speed ease, transform color ease transition border transition-speed ease, background transition-speed ease, transform transition-speed ease, transform color ease
@ -29,14 +29,14 @@
width 100% width 100%
// max-width 700px // max-width 700px
.widget-element-text .widget-ui-element-text
horizontal horizontal
clip-long-text clip-long-text
justify-content flex-start justify-content flex-start
align-items center align-items center
width 100% width 100%
.widget-input .widget-section
vertical vertical
width 100% width 100%