Polish launcher main and library flows
Some checks failed
Build / release (macos-latest) (push) Has been cancelled
Build / release (ubuntu-latest) (push) Has been cancelled
Build / release (windows-latest) (push) Has been cancelled
Windows Smoke Test / windows-smoke (push) Has been cancelled

This commit is contained in:
2026-05-04 15:10:36 +09:00
parent 27c1453aa8
commit bc6bef0c46
13 changed files with 255 additions and 291 deletions

View File

@@ -2470,18 +2470,18 @@ input:checked + .toggleSwitchSlider:before {
} }
#landingContainer > #upper > #left { #landingContainer > #upper > #left {
display: inline-flex; display: inline-flex;
width: 15%; width: 14%;
height: 100%; height: 100%;
justify-content: flex-end; justify-content: flex-end;
} }
#landingContainer > #upper > #content { #landingContainer > #upper > #content {
display: inline-flex; display: inline-flex;
width: 63%; width: 58%;
height: 100%; height: 100%;
} }
#landingContainer > #upper > #right { #landingContainer > #upper > #right {
display: inline-flex; display: inline-flex;
width: 22%; width: 28%;
height: 100%; height: 100%;
justify-content: flex-end; justify-content: flex-end;
} }
@@ -2505,7 +2505,7 @@ input:checked + .toggleSwitchSlider:before {
position: relative; position: relative;
top: 25px; top: 25px;
display: inline-flex; display: inline-flex;
line-height: 24px; line-height: 28px;
left: 50px; left: 50px;
} }
#landingContainer > #lower > #center { #landingContainer > #lower > #center {
@@ -2991,19 +2991,19 @@ input:checked + .toggleSwitchSlider:before {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-end; align-items: flex-end;
gap: 4px; gap: 6px;
min-width: 150px; min-width: 210px;
} }
#accountPreviewLabel { #accountPreviewLabel {
font-size: 11px; font-size: 13px;
letter-spacing: 0.12em; letter-spacing: 0.12em;
text-transform: uppercase; text-transform: uppercase;
color: rgba(255, 255, 255, 0.58); color: rgba(255, 255, 255, 0.58);
} }
#accountPreviewName { #accountPreviewName {
font-size: 13px; font-size: 18px;
font-weight: 800; font-weight: 800;
color: #ffffff; color: #ffffff;
text-align: right; text-align: right;
@@ -3028,11 +3028,11 @@ input:checked + .toggleSwitchSlider:before {
/* User profile avatar container. */ /* User profile avatar container. */
#avatarContainer { #avatarContainer {
border-radius: 50%; border-radius: 50%;
border: 2px solid #cad7e1; border: 3px solid #cad7e1;
box-sizing: border-box; box-sizing: border-box;
background: rgba(1, 2, 1, 0.5); background: rgba(1, 2, 1, 0.5);
height: 70px; height: 88px;
width: 70px; width: 88px;
box-shadow: 0px 0px 10px 0px rgb(0, 0, 0); box-shadow: 0px 0px 10px 0px rgb(0, 0, 0);
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@@ -3049,16 +3049,16 @@ input:checked + .toggleSwitchSlider:before {
} }
#accountMenu { #accountMenu {
min-width: 190px; min-width: 220px;
padding: 14px; padding: 16px;
border-radius: 16px; border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(10, 10, 10, 0.9); background: rgba(10, 10, 10, 0.9);
backdrop-filter: blur(12px); backdrop-filter: blur(12px);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
gap: 12px; gap: 14px;
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28); box-shadow: 0 18px 40px rgba(0, 0, 0, 0.28);
} }
@@ -3067,7 +3067,7 @@ input:checked + .toggleSwitchSlider:before {
} }
#accountMenuName { #accountMenuName {
font-size: 13px; font-size: 16px;
font-weight: 800; font-weight: 800;
letter-spacing: 0.04em; letter-spacing: 0.04em;
color: #ffffff; color: #ffffff;
@@ -3083,9 +3083,9 @@ input:checked + .toggleSwitchSlider:before {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin-top: 25px; margin-top: 32px;
height: calc(100% - 95px); height: calc(100% - 120px);
width: 70px; width: 82px;
align-items: center; align-items: center;
} }
@@ -3100,13 +3100,13 @@ input:checked + .toggleSwitchSlider:before {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 27px; height: 36px;
} }
/* Divider bar between the external and internal icons. */ /* Divider bar between the external and internal icons. */
.mediaDivider { .mediaDivider {
height: 1px; height: 1px;
width: 14px; width: 18px;
background: rgb(255, 255, 255); background: rgb(255, 255, 255);
margin: 10px 0px; margin: 10px 0px;
} }
@@ -3114,16 +3114,15 @@ input:checked + .toggleSwitchSlider:before {
/* Social media icon shared styles. */ /* Social media icon shared styles. */
.mediaSVG { .mediaSVG {
fill: #ffffff; fill: #ffffff;
height: 12px;
transition: 0.25s ease; transition: 0.25s ease;
cursor: pointer; cursor: pointer;
height: 12px; height: 16px;
width: 25px; width: 32px;
} }
.mediaSVG:hover, .mediaSVG:hover,
.mediaURL:focus .mediaSVG, .mediaURL:focus .mediaSVG,
.mediaSVG:active { .mediaSVG:active {
height: 20px; height: 24px;
} }
/* Social media URL shared styles. */ /* Social media URL shared styles. */
@@ -3148,28 +3147,28 @@ input:checked + .toggleSwitchSlider:before {
/* Settings icon colors. */ /* Settings icon colors. */
#settingsSVG { #settingsSVG {
stroke: #ffffff; stroke: #ffffff;
height: 15px; height: 18px;
} }
.mediaButton:hover #settingsSVG, .mediaButton:hover #settingsSVG,
.mediaButton:focus #settingsSVG, .mediaButton:focus #settingsSVG,
.mediaButton:active #settingsSVG { .mediaButton:active #settingsSVG {
height: 23px; height: 27px;
} }
/* Settings tooltip styles. */ /* Settings tooltip styles. */
#settingsTooltip { #settingsTooltip {
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
width: 75px; width: 88px;
height: 20px; height: 24px;
background-color: rgba(0, 0, 0, 0.75); background-color: rgba(0, 0, 0, 0.75);
text-align: center; text-align: center;
border-radius: 4px; border-radius: 4px;
position: absolute; position: absolute;
z-index: 1; z-index: 1;
right: 130%; right: 130%;
font-size: 12px; font-size: 13px;
line-height: 20px; line-height: 24px;
transition: visibility 0s linear 0.25s, opacity 0.25s ease; transition: visibility 0s linear 0.25s, opacity 0.25s ease;
} }
#settingsTooltip::after { #settingsTooltip::after {
@@ -3262,19 +3261,19 @@ input:checked + .toggleSwitchSlider:before {
/* Style for a general label on the bottom of the landing view. */ /* Style for a general label on the bottom of the landing view. */
.bot_label { .bot_label {
font-size: 10px; font-size: 13px;
letter-spacing: 1px; letter-spacing: 1.2px;
font-weight: bold; font-weight: bold;
text-shadow: 0px 0px 0px #bebcbb; text-shadow: 0px 0px 0px #bebcbb;
} }
/* Divider used on the bottom of the landing view. */ /* Divider used on the bottom of the landing view. */
.bot_divider { .bot_divider {
height: 25px; height: 30px;
width: 2px; width: 2px;
background: rgba(107, 105, 105, 0.7); background: rgba(107, 105, 105, 0.7);
margin-left: 20px; margin-left: 22px;
margin-right: 20px; margin-right: 22px;
} }
/* * * /* * *
@@ -3284,16 +3283,16 @@ input:checked + .toggleSwitchSlider:before {
/* Maintains maximum width on the status bar. */ /* Maintains maximum width on the status bar. */
#server_status_wrapper { #server_status_wrapper {
display: inline-flex; display: inline-flex;
width: 80px; width: 180px;
} }
/* Span which displays the player count of the selected server. */ /* Span which displays the player count of the selected server. */
#player_count { #player_count {
color: #949494; color: #949494;
font-size: 9px; font-size: 14px;
font-weight: 900; font-weight: 900;
text-shadow: 0px 0px 20px #949494; text-shadow: 0px 0px 20px #949494;
margin-left: 10px; margin-left: 12px;
} }
/* Wrapper container for the mojang status bar. */ /* Wrapper container for the mojang status bar. */
@@ -3305,9 +3304,9 @@ input:checked + .toggleSwitchSlider:before {
/* Icon which displays the status of the mojang services. */ /* Icon which displays the status of the mojang services. */
#mojang_status_icon { #mojang_status_icon {
font-size: 30px; font-size: 34px;
color: #848484; color: #848484;
margin-left: 15px; margin-left: 16px;
font-family: 'sans-serif'; font-family: 'sans-serif';
} }
@@ -3316,7 +3315,7 @@ input:checked + .toggleSwitchSlider:before {
position: absolute; position: absolute;
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
width: 145px; width: 175px;
min-height: 150px; min-height: 150px;
background-color: rgba(0, 0, 0, 0.75); background-color: rgba(0, 0, 0, 0.75);
color: #fff; color: #fff;
@@ -3324,7 +3323,7 @@ input:checked + .toggleSwitchSlider:before {
padding: 5px 10px; padding: 5px 10px;
z-index: 1; z-index: 1;
font-family: 'Pretendard Medium'; font-family: 'Pretendard Medium';
font-size: 12px; font-size: 13px;
transition: visibility 0s linear 0.25s, opacity 0.25s ease; transition: visibility 0s linear 0.25s, opacity 0.25s ease;
bottom: calc(100% + 15px); bottom: calc(100% + 15px);
transform: translateX(-50%); transform: translateX(-50%);
@@ -3372,7 +3371,7 @@ input:checked + .toggleSwitchSlider:before {
/* Non essential service title text. */ /* Non essential service title text. */
#mojangStatusNETitle { #mojangStatusNETitle {
font-size: 10px; font-size: 11px;
padding: 0px 3px; padding: 0px 3px;
text-align: center; text-align: center;
letter-spacing: 1px; letter-spacing: 1px;
@@ -3386,16 +3385,16 @@ input:checked + .toggleSwitchSlider:before {
/* Displays the name of the mojang service. */ /* Displays the name of the mojang service. */
.mojangStatusName { .mojangStatusName {
width: 100%; width: 100%;
font-size: 10px; font-size: 12px;
letter-spacing: 1px; letter-spacing: 1px;
line-height: 12px; line-height: 14px;
padding: 6px 0px; padding: 7px 0px;
} }
/* Displays the status of the mojang service. */ /* Displays the status of the mojang service. */
.mojangStatusIcon { .mojangStatusIcon {
margin-right: 10px; margin-right: 10px;
font-size: 18.5px; font-size: 20px;
color: #848484; color: #848484;
} }
@@ -3409,6 +3408,9 @@ input:checked + .toggleSwitchSlider:before {
border: none; border: none;
cursor: pointer; cursor: pointer;
outline: none; outline: none;
display: inline-flex;
align-items: center;
justify-content: center;
} }
#newsButton:hover #newsButtonText, #newsButton:hover #newsButtonText,
#newsButton:focus #newsButtonText { #newsButton:focus #newsButtonText {
@@ -3455,10 +3457,10 @@ input:checked + .toggleSwitchSlider:before {
#newsButtonText { #newsButtonText {
color: white; color: white;
font-weight: 900; font-weight: 900;
letter-spacing: 2px; letter-spacing: 2.5px;
text-shadow: 0px 0px 0px #bebcbb; text-shadow: 0px 0px 0px #bebcbb;
font-size: 11px; font-size: 16px;
line-height: 30px; line-height: 36px;
display: flex; display: flex;
transition: 0.25s ease; transition: 0.25s ease;
} }
@@ -3482,7 +3484,7 @@ input:checked + .toggleSwitchSlider:before {
font-weight: 900; font-weight: 900;
letter-spacing: 2px; letter-spacing: 2px;
text-shadow: 0px 0px 0px #bebcbb; text-shadow: 0px 0px 0px #bebcbb;
font-size: 20px; font-size: 28px;
padding: 0px; padding: 0px;
transition: 0.25s ease; transition: 0.25s ease;
outline: none; outline: none;
@@ -3518,9 +3520,9 @@ input:checked + .toggleSwitchSlider:before {
font-weight: 900; font-weight: 900;
letter-spacing: 1px; letter-spacing: 1px;
text-shadow: 0px 0px 0px #bebcbb; text-shadow: 0px 0px 0px #bebcbb;
font-size: 20px; font-size: 24px;
min-width: 53.21px; min-width: 64px;
max-width: 53.21px; max-width: 64px;
text-align: right; text-align: right;
} }
@@ -3537,7 +3539,8 @@ input:checked + .toggleSwitchSlider:before {
border: none; border: none;
outline: none; outline: none;
cursor: pointer; cursor: pointer;
line-height: 24px; font-size: 15px;
line-height: 30px;
padding: 0px; padding: 0px;
transition: 0.25s ease; transition: 0.25s ease;
} }
@@ -3552,8 +3555,8 @@ input:checked + .toggleSwitchSlider:before {
/* Progress bar styles. */ /* Progress bar styles. */
#launch_progress[value] { #launch_progress[value] {
height: 3px; height: 4px;
width: 265px; width: 320px;
-webkit-appearance: none; -webkit-appearance: none;
} }
#launch_progress[value]::-webkit-progress-bar { #launch_progress[value]::-webkit-progress-bar {
@@ -3565,7 +3568,7 @@ input:checked + .toggleSwitchSlider:before {
/* Span which displays information about the status of the launch process. */ /* Span which displays information about the status of the launch process. */
#launch_details_text { #launch_details_text {
font-size: 11px; font-size: 13px;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@@ -4079,8 +4082,8 @@ input:checked + .toggleSwitchSlider:before {
.launcherPageEyebrow { .launcherPageEyebrow {
display: inline-block; display: inline-block;
margin-bottom: 8px; margin-bottom: 10px;
font-size: 12px; font-size: 13px;
letter-spacing: 0.16em; letter-spacing: 0.16em;
text-transform: uppercase; text-transform: uppercase;
color: rgba(255, 255, 255, 0.65); color: rgba(255, 255, 255, 0.65);
@@ -4088,14 +4091,15 @@ input:checked + .toggleSwitchSlider:before {
.launcherPageTitle { .launcherPageTitle {
margin: 0; margin: 0;
font-size: 32px; font-size: 38px;
font-weight: 700; font-weight: 700;
color: #ffffff; color: #ffffff;
} }
.launcherPageSubtitle { .launcherPageSubtitle {
max-width: 680px; max-width: 760px;
margin: 10px 0 0; margin: 12px 0 0;
font-size: 16px;
line-height: 1.5; line-height: 1.5;
color: rgba(255, 255, 255, 0.74); color: rgba(255, 255, 255, 0.74);
} }
@@ -4103,12 +4107,12 @@ input:checked + .toggleSwitchSlider:before {
.launcherBackButton { .launcherBackButton {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 8px; gap: 10px;
padding: 0; padding: 0;
border: none; border: none;
background: none; background: none;
color: rgba(255, 255, 255, 0.88); color: rgba(255, 255, 255, 0.88);
font-size: 13px; font-size: 16px;
font-weight: 700; font-weight: 700;
letter-spacing: 0.04em; letter-spacing: 0.04em;
cursor: pointer; cursor: pointer;
@@ -4116,7 +4120,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherBackButton::before { .launcherBackButton::before {
content: '←'; content: '←';
font-size: 16px; font-size: 20px;
} }
.launcherBackButton:hover, .launcherBackButton:hover,
@@ -4135,7 +4139,7 @@ input:checked + .toggleSwitchSlider:before {
#landingNavButtons { #landingNavButtons {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 12px;
flex-wrap: wrap; flex-wrap: wrap;
} }
@@ -4154,17 +4158,17 @@ input:checked + .toggleSwitchSlider:before {
.launcherListContainer { .launcherListContainer {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: 14px;
} }
.launcherListItem { .launcherListItem {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 16px; gap: 20px;
padding: 18px 20px; padding: 22px 24px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 18px; border-radius: 20px;
background: rgba(15, 15, 15, 0.56); background: rgba(15, 15, 15, 0.56);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18); box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18);
@@ -4200,7 +4204,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherListTitle { .launcherListTitle {
margin: 0; margin: 0;
font-size: 20px; font-size: 24px;
color: #ffffff; color: #ffffff;
} }
@@ -4213,6 +4217,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherListDescription { .launcherListDescription {
margin: 0; margin: 0;
font-size: 15px;
line-height: 1.5; line-height: 1.5;
color: rgba(255, 255, 255, 0.76); color: rgba(255, 255, 255, 0.76);
} }
@@ -4228,11 +4233,11 @@ input:checked + .toggleSwitchSlider:before {
.launcherCard { .launcherCard {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 14px; gap: 16px;
min-height: 220px; min-height: 240px;
padding: 18px; padding: 22px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 18px; border-radius: 20px;
background: rgba(15, 15, 15, 0.56); background: rgba(15, 15, 15, 0.56);
backdrop-filter: blur(10px); backdrop-filter: blur(10px);
box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18); box-shadow: 0 18px 50px rgba(0, 0, 0, 0.18);
@@ -4257,7 +4262,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherCardTitle { .launcherCardTitle {
margin: 0; margin: 0;
font-size: 22px; font-size: 26px;
color: #ffffff; color: #ffffff;
} }
@@ -4271,10 +4276,10 @@ input:checked + .toggleSwitchSlider:before {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 4px 10px; padding: 5px 12px;
border-radius: 999px; border-radius: 999px;
background: rgba(255, 255, 255, 0.12); background: rgba(255, 255, 255, 0.12);
font-size: 11px; font-size: 12px;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em; letter-spacing: 0.08em;
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
@@ -4283,6 +4288,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherCardDescription, .launcherCardDescription,
.launcherNotice span, .launcherNotice span,
.launcherEmptyDescription { .launcherEmptyDescription {
font-size: 15px;
line-height: 1.5; line-height: 1.5;
color: rgba(255, 255, 255, 0.76); color: rgba(255, 255, 255, 0.76);
} }
@@ -4296,7 +4302,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherEditorTitle { .launcherEditorTitle {
display: block; display: block;
font-size: 18px; font-size: 22px;
font-weight: 700; font-weight: 700;
color: #ffffff; color: #ffffff;
} }
@@ -4304,17 +4310,19 @@ input:checked + .toggleSwitchSlider:before {
.launcherEditorDescription { .launcherEditorDescription {
display: block; display: block;
margin-top: 6px; margin-top: 6px;
font-size: 15px;
line-height: 1.5; line-height: 1.5;
color: rgba(255, 255, 255, 0.72); color: rgba(255, 255, 255, 0.72);
} }
.launcherDetailBody { .launcherDetailBody {
box-sizing: border-box; box-sizing: border-box;
min-height: 140px; min-height: 180px;
padding: 14px 16px; padding: 16px 18px;
border-radius: 14px; border-radius: 14px;
background: rgba(255, 255, 255, 0.04); background: rgba(255, 255, 255, 0.04);
color: rgba(255, 255, 255, 0.84); color: rgba(255, 255, 255, 0.84);
font-size: 15px;
line-height: 1.6; line-height: 1.6;
white-space: pre-wrap; white-space: pre-wrap;
} }
@@ -4322,8 +4330,8 @@ input:checked + .toggleSwitchSlider:before {
.launcherInfoBlock { .launcherInfoBlock {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 10px;
padding: 12px 14px; padding: 14px 16px;
border-radius: 14px; border-radius: 14px;
background: rgba(255, 255, 255, 0.04); background: rgba(255, 255, 255, 0.04);
} }
@@ -4335,7 +4343,7 @@ input:checked + .toggleSwitchSlider:before {
} }
.launcherInfoLabel { .launcherInfoLabel {
font-size: 12px; font-size: 13px;
color: rgba(255, 255, 255, 0.58); color: rgba(255, 255, 255, 0.58);
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
@@ -4343,6 +4351,7 @@ input:checked + .toggleSwitchSlider:before {
.launcherInfoValue { .launcherInfoValue {
text-align: right; text-align: right;
font-size: 15px;
color: rgba(255, 255, 255, 0.88); color: rgba(255, 255, 255, 0.88);
} }
@@ -4373,7 +4382,7 @@ input:checked + .toggleSwitchSlider:before {
} }
.launcherFieldLabel { .launcherFieldLabel {
font-size: 12px; font-size: 13px;
color: rgba(255, 255, 255, 0.65); color: rgba(255, 255, 255, 0.65);
letter-spacing: 0.08em; letter-spacing: 0.08em;
text-transform: uppercase; text-transform: uppercase;
@@ -4412,10 +4421,10 @@ input:checked + .toggleSwitchSlider:before {
.launcherPrimaryButton, .launcherPrimaryButton,
.launcherSecondaryButton, .launcherSecondaryButton,
.launcherGhostButton { .launcherGhostButton {
padding: 11px 16px; padding: 13px 18px;
border-radius: 12px; border-radius: 14px;
border: 1px solid transparent; border: 1px solid transparent;
font-size: 14px; font-size: 16px;
font-weight: 600; font-weight: 600;
cursor: pointer; cursor: pointer;
transition: transform 0.2s ease, opacity 0.2s ease, border-color 0.2s ease, background 0.2s ease; transition: transform 0.2s ease, opacity 0.2s ease, border-color 0.2s ease, background 0.2s ease;
@@ -4456,9 +4465,9 @@ input:checked + .toggleSwitchSlider:before {
.launcherNotice { .launcherNotice {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 6px; gap: 8px;
padding: 18px; padding: 20px;
border-radius: 18px; border-radius: 20px;
background: rgba(8, 8, 8, 0.42); background: rgba(8, 8, 8, 0.42);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.08);
} }

View File

@@ -227,10 +227,10 @@ async function renderInstallView(){
const detailButton = document.createElement('button') const detailButton = document.createElement('button')
detailButton.className = 'launcherSecondaryButton' detailButton.className = 'launcherSecondaryButton'
detailButton.textContent = '자세히 보기' detailButton.textContent = '자세히 보기'
detailButton.addEventListener('click', (event) => { detailButton.addEventListener('click', async (event) => {
event.stopPropagation() event.stopPropagation()
selectProfile(profile.id) selectProfile(profile.id)
renderInstallView() await renderInstallView()
}) })
const installButton = document.createElement('button') const installButton = document.createElement('button')
@@ -248,6 +248,9 @@ async function renderInstallView(){
if(typeof refreshSelectedProfileButton === 'function'){ if(typeof refreshSelectedProfileButton === 'function'){
refreshSelectedProfileButton() refreshSelectedProfileButton()
} }
if(typeof refreshServerStatus === 'function'){
refreshServerStatus(true)
}
selectProfile(profile.id) selectProfile(profile.id)
await renderInstallView() await renderInstallView()
if(typeof refreshLibraryView === 'function'){ if(typeof refreshLibraryView === 'function'){
@@ -270,9 +273,9 @@ async function renderInstallView(){
main.appendChild(description) main.appendChild(description)
row.appendChild(main) row.appendChild(main)
row.appendChild(actions) row.appendChild(actions)
row.addEventListener('click', () => { row.addEventListener('click', async () => {
selectProfile(profile.id) selectProfile(profile.id)
renderInstallView() await renderInstallView()
}) })
installCatalogList.appendChild(row) installCatalogList.appendChild(row)
} }
@@ -300,22 +303,10 @@ async function renderInstallView(){
} }
} }
document.getElementById('installOpenSettingsButton').addEventListener('click', async () => {
await prepareSettings()
switchView(getCurrentView(), VIEWS.settings)
})
document.getElementById('installBackButton').addEventListener('click', () => { document.getElementById('installBackButton').addEventListener('click', () => {
switchView(getCurrentView(), VIEWS.landing) switchView(getCurrentView(), VIEWS.landing)
}) })
document.getElementById('installBackToLibraryButton').addEventListener('click', async () => {
if(typeof refreshLibraryView === 'function'){
await refreshLibraryView()
}
switchView(getCurrentView(), VIEWS.library)
})
document.getElementById('installDetailOpenLibraryButton').addEventListener('click', async () => { document.getElementById('installDetailOpenLibraryButton').addEventListener('click', async () => {
if(typeof refreshLibraryView === 'function'){ if(typeof refreshLibraryView === 'function'){
await refreshLibraryView() await refreshLibraryView()

View File

@@ -187,6 +187,19 @@ function refreshSelectedProfileButton(){
setLaunchEnabled(selectedProfile.configured !== false) setLaunchEnabled(selectedProfile.configured !== false)
} }
function isSelectedMapReady(profile){
if(profile == null || profile.kind !== 'map'){
return false
}
const assetState = ConfigManager.getLibraryProfileAssetState(profile.id)
return profile.launchReady && (
assetState.worldInstalledAt != null ||
assetState.prefetchedAt != null ||
profile.worldArchiveUrl == null
)
}
// Bind launch button // Bind launch button
document.getElementById('launch_button').addEventListener('click', async e => { document.getElementById('launch_button').addEventListener('click', async e => {
loggerLanding.info('Launching game..') loggerLanding.info('Launching game..')
@@ -253,20 +266,6 @@ document.getElementById('settingsMediaButton').onclick = async e => {
switchView(getCurrentView(), VIEWS.settings) switchView(getCurrentView(), VIEWS.settings)
} }
document.getElementById('landingLibraryButton').onclick = async () => {
if(typeof refreshLibraryView === 'function'){
await refreshLibraryView()
}
switchView(getCurrentView(), VIEWS.library)
}
document.getElementById('landingInstallButton').onclick = async () => {
if(typeof refreshInstallView === 'function'){
await refreshInstallView()
}
switchView(getCurrentView(), VIEWS.install)
}
avatarMenuButton.addEventListener('click', (e) => { avatarMenuButton.addEventListener('click', (e) => {
e.stopPropagation() e.stopPropagation()
setAccountMenuOpen(accountMenu.hasAttribute('hidden')) setAccountMenuOpen(accountMenu.hasAttribute('hidden'))
@@ -391,15 +390,56 @@ const refreshMojangStatuses = async function(){
const refreshServerStatus = async (fade = false) => { const refreshServerStatus = async (fade = false) => {
loggerLanding.info('Refreshing Server Status') loggerLanding.info('Refreshing Server Status')
const serv = (await DistroAPI.getDistribution()).getServerById(ConfigManager.getSelectedServer()) const selectedProfile = CatalogManager.getSelectedProfileSync()
let pLabel = Lang.queryJS('landing.serverStatus.server') let pLabel = Lang.queryJS('landing.profileStatus.label')
let pVal = Lang.queryJS('landing.serverStatus.offline') let pVal = Lang.queryJS('landing.selectedProfile.noSelection')
if(selectedProfile == null){
if(fade){
$('#server_status_wrapper').fadeOut(250, () => {
document.getElementById('landingPlayerLabel').innerHTML = pLabel
document.getElementById('player_count').innerHTML = pVal
$('#server_status_wrapper').fadeIn(500)
})
} else {
document.getElementById('landingPlayerLabel').innerHTML = pLabel
document.getElementById('player_count').innerHTML = pVal
}
return
}
if(selectedProfile.kind === 'map'){
pLabel = Lang.queryJS('landing.mapStatus.label')
pVal = isSelectedMapReady(selectedProfile)
? Lang.queryJS('landing.mapStatus.ready')
: Lang.queryJS('landing.mapStatus.notReady')
if(fade){
$('#server_status_wrapper').fadeOut(250, () => {
document.getElementById('landingPlayerLabel').innerHTML = pLabel
document.getElementById('player_count').innerHTML = pVal
$('#server_status_wrapper').fadeIn(500)
})
} else {
document.getElementById('landingPlayerLabel').innerHTML = pLabel
document.getElementById('player_count').innerHTML = pVal
}
return
}
pLabel = Lang.queryJS('landing.serverStatus.server')
pVal = Lang.queryJS('landing.serverStatus.offline')
try { try {
const distro = await DistroAPI.getDistribution()
const serv = distro?.getServerById(ConfigManager.getSelectedServer())
?? (typeof distro?.getMainServer === 'function' ? distro.getMainServer() : null)
if(serv == null){
throw new Error('No server available for selected profile.')
}
const servStat = await getServerStatus(47, serv.hostname, serv.port) const servStat = await getServerStatus(47, serv.hostname, serv.port)
console.log(servStat)
pLabel = Lang.queryJS('landing.serverStatus.players') pLabel = Lang.queryJS('landing.serverStatus.players')
pVal = servStat.players.online + '/' + servStat.players.max pVal = servStat.players.online + '/' + servStat.players.max
@@ -857,24 +897,12 @@ function slide_(up){
} }
} }
// Bind news button. // Bind install button on the landing footer.
document.getElementById('newsButton').onclick = () => { document.getElementById('newsButton').onclick = () => {
// Toggle tabbing. if(typeof refreshInstallView === 'function'){
if(newsActive){ refreshInstallView()
$('#landingContainer *').removeAttr('tabindex')
$('#newsContainer *').attr('tabindex', '-1')
} else {
$('#landingContainer *').attr('tabindex', '-1')
$('#newsContainer, #newsContainer *, #lower, #lower #center *').removeAttr('tabindex')
if(newsAlertShown){
$('#newsButtonAlert').fadeOut(2000)
newsAlertShown = false
ConfigManager.setNewsCacheDismissed(true)
ConfigManager.save()
} }
} switchView(getCurrentView(), VIEWS.install)
slide_(!newsActive)
newsActive = !newsActive
} }
// Array to store article meta. // Array to store article meta.
@@ -1073,12 +1101,6 @@ document.addEventListener('keydown', (e) => {
// if(e.key === 'ArrowDown'){ // if(e.key === 'ArrowDown'){
// document.getElementById('newsButton').click() // document.getElementById('newsButton').click()
// } // }
} else {
if(getCurrentView() === VIEWS.landing){
if(e.key === 'ArrowUp'){
document.getElementById('newsButton').click()
}
}
} }
}) })

View File

@@ -89,6 +89,20 @@ function describeAssetState(profile){
return '추가 자산 없음' return '추가 자산 없음'
} }
function isProfileInstalled(profile){
const state = ConfigManager.getLibraryProfileAssetState(profile.id)
if(profile.kind === 'map'){
return state.prefetchedAt != null || profile.worldArchiveUrl == null
}
if(profile.kind === 'server-pack'){
return state.serverBundleInstalledAt != null || state.prefetchedAt != null || profile.serverBundleUrl == null
}
return true
}
async function prepareProfileAssets(profile){ async function prepareProfileAssets(profile){
try { try {
await ProfileAssetManager.prefetchProfileAssets(profile) await ProfileAssetManager.prefetchProfileAssets(profile)
@@ -103,6 +117,27 @@ async function prepareProfileAssets(profile){
} }
} }
async function applyProfileSelection(profile){
CatalogManager.selectProfile(profile.id)
CatalogManager.applyConfiguredProfile()
const distro = await DistroAPI.refreshDistributionOrFallback()
if(distro == null){
throw new Error('Distribution refresh returned null.')
}
const currentServer = distro.getServerById(ConfigManager.getSelectedServer())
if(currentServer == null && typeof distro.getMainServer === 'function'){
const mainServer = distro.getMainServer()
if(mainServer != null){
ConfigManager.setSelectedServer(mainServer.rawServer.id)
ConfigManager.save()
}
}
onDistroRefresh(distro)
}
async function activateProfile(profile, launchNow = false){ async function activateProfile(profile, launchNow = false){
if(!profile.configured){ if(!profile.configured){
const firstIssue = profile.launchIssues?.[0] ?? '이 프로필은 아직 실행 조건이 충족되지 않았습니다.' const firstIssue = profile.launchIssues?.[0] ?? '이 프로필은 아직 실행 조건이 충족되지 않았습니다.'
@@ -264,101 +299,39 @@ async function renderLibraryView(){
const description = createParagraph('launcherCardDescription', profile.description || '설명이 없습니다.') const description = createParagraph('launcherCardDescription', profile.description || '설명이 없습니다.')
const infoBlock = document.createElement('div')
infoBlock.className = 'launcherInfoBlock'
infoBlock.appendChild(createInfoLine('자료 상태', describeAssetState(profile)))
infoBlock.appendChild(createInfoLine('실행 준비', profile.launchReady ? '완료' : '추가 설정 필요'))
if(profile.defaultServerAddress){
infoBlock.appendChild(createInfoLine('기본 주소', profile.defaultServerAddress))
}
if(profile.kind === 'server-pack'){
infoBlock.appendChild(createInfoLine('로컬 호스팅', profile.hostReady ? '가능' : '서버 번들 필요'))
}
if(hostState.running){
infoBlock.appendChild(createInfoLine('호스트 상태', hostState.tunneling ? '터널 연결 중' : '로컬 서버 실행 중'))
}
if(profile.launchIssues?.length > 0){
infoBlock.appendChild(createInfoLine('확인 필요', profile.launchIssues[0]))
} else if(profile.hostIssues?.length > 0){
infoBlock.appendChild(createInfoLine('호스팅 확인', profile.hostIssues[0]))
}
const fieldGroup = document.createElement('div')
fieldGroup.className = 'launcherFieldGroup'
appendAddressOverrideField(profile, fieldGroup)
appendPublishedAddressField(profile, hostState, fieldGroup)
const actions = document.createElement('div') const actions = document.createElement('div')
actions.className = 'launcherCardActions' actions.className = 'launcherCardActions'
const prepareButton = document.createElement('button') const installButton = document.createElement('button')
prepareButton.className = 'launcherSecondaryButton' installButton.className = 'launcherSecondaryButton'
prepareButton.textContent = '자료 준비' installButton.textContent = isProfileInstalled(profile) ? '설치됨' : '설치'
prepareButton.addEventListener('click', async () => { installButton.disabled = isProfileInstalled(profile) || !profile.configured
installButton.addEventListener('click', async () => {
await prepareProfileAssets(profile) await prepareProfileAssets(profile)
}) })
const selectButton = document.createElement('button') const selectButton = document.createElement('button')
selectButton.className = 'launcherSecondaryButton' selectButton.className = 'launcherSecondaryButton'
selectButton.textContent = '프로필 선택' selectButton.textContent = profile.id === selectedProfileId ? '선택됨' : '선택'
selectButton.disabled = !profile.configured selectButton.disabled = profile.id === selectedProfileId
selectButton.addEventListener('click', async () => { selectButton.addEventListener('click', async () => {
CatalogManager.selectProfile(profile.id) try {
CatalogManager.applyConfiguredProfile() await applyProfileSelection(profile)
if(typeof refreshSelectedProfileButton === 'function'){ if(typeof refreshSelectedProfileButton === 'function'){
refreshSelectedProfileButton() refreshSelectedProfileButton()
} }
await renderLibraryView() if(typeof refreshServerStatus === 'function'){
}) refreshServerStatus(true)
}
const openButton = document.createElement('button')
openButton.className = 'launcherSecondaryButton'
openButton.textContent = '실행 화면'
openButton.disabled = !profile.configured
openButton.addEventListener('click', async () => {
await activateProfile(profile, false)
})
const launchButton = document.createElement('button')
launchButton.className = 'launcherPrimaryButton'
launchButton.textContent = profile.kind === 'map' ? '맵 실행' : '바로 실행'
launchButton.disabled = !profile.configured
launchButton.addEventListener('click', async () => {
await activateProfile(profile, true)
})
actions.appendChild(prepareButton)
actions.appendChild(selectButton)
actions.appendChild(openButton)
actions.appendChild(launchButton)
if(profile.kind === 'server-pack'){
const startHostButton = document.createElement('button')
startHostButton.className = 'launcherSecondaryButton'
startHostButton.textContent = '서버 실행'
startHostButton.disabled = hostState.running || !profile.hostReady
startHostButton.addEventListener('click', async () => {
try {
await ServerRuntime.startHostedProfile(profile)
await renderLibraryView() await renderLibraryView()
} catch (error) { } catch (error) {
console.error(error) console.error(error)
showLibraryMessage('서버 실행 실패', '서버 번들이 준비되지 않았거나 시작 명령을 찾지 못했습니다.') showLibraryMessage('프로필 선택 실패', '선택한 프로필의 배포 정보 또는 서버 정보를 불러오지 못했습니다.')
} }
}) })
const stopHostButton = document.createElement('button') actions.appendChild(installButton)
stopHostButton.className = 'launcherGhostButton' actions.appendChild(selectButton)
stopHostButton.textContent = '서버 중지'
stopHostButton.disabled = !hostState.running
stopHostButton.addEventListener('click', async () => {
ServerRuntime.stopHostedProfile(profile.id)
await renderLibraryView()
})
actions.appendChild(startHostButton)
actions.appendChild(stopHostButton)
}
const removeButton = document.createElement('button') const removeButton = document.createElement('button')
removeButton.className = 'launcherGhostButton' removeButton.className = 'launcherGhostButton'
@@ -369,6 +342,9 @@ async function renderLibraryView(){
if(typeof refreshSelectedProfileButton === 'function'){ if(typeof refreshSelectedProfileButton === 'function'){
refreshSelectedProfileButton() refreshSelectedProfileButton()
} }
if(typeof refreshServerStatus === 'function'){
refreshServerStatus(true)
}
await renderLibraryView() await renderLibraryView()
if(typeof refreshInstallView === 'function'){ if(typeof refreshInstallView === 'function'){
await refreshInstallView() await refreshInstallView()
@@ -379,10 +355,6 @@ async function renderLibraryView(){
card.appendChild(header) card.appendChild(header)
card.appendChild(description) card.appendChild(description)
card.appendChild(infoBlock)
if(fieldGroup.childNodes.length > 0){
card.appendChild(fieldGroup)
}
card.appendChild(actions) card.appendChild(actions)
libraryList.appendChild(card) libraryList.appendChild(card)
} }
@@ -396,31 +368,10 @@ async function renderLibraryView(){
} }
} }
document.getElementById('libraryOpenInstallButton').addEventListener('click', async () => {
if(typeof refreshInstallView === 'function'){
await refreshInstallView()
}
switchView(getCurrentView(), VIEWS.install)
})
document.getElementById('libraryBackButton').addEventListener('click', () => { document.getElementById('libraryBackButton').addEventListener('click', () => {
switchView(getCurrentView(), VIEWS.landing) switchView(getCurrentView(), VIEWS.landing)
}) })
document.getElementById('libraryOpenSettingsButton').addEventListener('click', async () => {
await prepareSettings()
switchView(getCurrentView(), VIEWS.settings)
})
document.getElementById('libraryOpenLaunchButton').addEventListener('click', async () => {
const selectedProfile = CatalogManager.getSelectedProfileSync()
if(selectedProfile == null){
switchView(getCurrentView(), VIEWS.install)
return
}
await activateProfile(selectedProfile, false)
})
setInterval(() => { setInterval(() => {
if(getCurrentView() === VIEWS.library && ServerRuntime.hasRunningProfiles()){ if(getCurrentView() === VIEWS.library && ServerRuntime.hasRunningProfiles()){
renderLibraryView() renderLibraryView()

View File

@@ -152,7 +152,7 @@ function formDisabled(v){
loginRememberOption.disabled = v loginRememberOption.disabled = v
} }
let loginViewOnSuccess = VIEWS.library let loginViewOnSuccess = VIEWS.landing
let loginViewOnCancel = VIEWS.settings let loginViewOnCancel = VIEWS.settings
let loginViewCancelHandler let loginViewCancelHandler
@@ -198,7 +198,7 @@ loginButton.addEventListener('click', () => {
if(loginViewOnSuccess === VIEWS.settings){ if(loginViewOnSuccess === VIEWS.settings){
await prepareSettings() await prepareSettings()
} }
loginViewOnSuccess = VIEWS.library // Reset this for good measure. loginViewOnSuccess = VIEWS.landing // Reset this for good measure.
loginCancelEnabled(false) // Reset this for good measure. loginCancelEnabled(false) // Reset this for good measure.
loginViewCancelHandler = null // Reset this for good measure. loginViewCancelHandler = null // Reset this for good measure.
loginUsername.value = '' loginUsername.value = ''

View File

@@ -337,7 +337,7 @@ function fullSettingsSave() {
/* Closes the settings view and saves all data. */ /* Closes the settings view and saves all data. */
settingsNavDone.onclick = () => { settingsNavDone.onclick = () => {
fullSettingsSave() fullSettingsSave()
switchView(getCurrentView(), VIEWS.library) switchView(getCurrentView(), VIEWS.landing)
} }
settingsBackButton.onclick = () => { settingsBackButton.onclick = () => {

View File

@@ -87,11 +87,11 @@ async function showMainUI(data){
$(VIEWS.welcome).fadeIn(1000) $(VIEWS.welcome).fadeIn(1000)
} else { } else {
if(isLoggedIn){ if(isLoggedIn){
currentView = VIEWS.library currentView = VIEWS.landing
$(VIEWS.library).fadeIn(1000) $(VIEWS.landing).fadeIn(1000)
} else { } else {
loginOptionsCancelEnabled(false) loginOptionsCancelEnabled(false)
loginOptionsViewOnLoginSuccess = VIEWS.library loginOptionsViewOnLoginSuccess = VIEWS.landing
loginOptionsViewOnLoginCancel = VIEWS.loginOptions loginOptionsViewOnLoginCancel = VIEWS.loginOptions
currentView = VIEWS.loginOptions currentView = VIEWS.loginOptions
$(VIEWS.loginOptions).fadeIn(1000) $(VIEWS.loginOptions).fadeIn(1000)
@@ -105,10 +105,6 @@ async function showMainUI(data){
}, 250) }, 250)
}, 750) }, 750)
// Disable tabbing to the news container.
initNews().then(() => {
$('#newsContainer *').attr('tabindex', '-1')
})
} }
function showFatalStartupError(){ function showFatalStartupError(){
@@ -137,7 +133,6 @@ function showFatalStartupError(){
function onDistroRefresh(data){ function onDistroRefresh(data){
updateSelectedServer(data.getServerById(ConfigManager.getSelectedServer())) updateSelectedServer(data.getServerById(ConfigManager.getSelectedServer()))
refreshServerStatus() refreshServerStatus()
initNews()
syncModConfigurations(data) syncModConfigurations(data)
ensureJavaSettings(data) ensureJavaSettings(data)
} }

View File

@@ -3,7 +3,7 @@
*/ */
document.getElementById('welcomeButton').addEventListener('click', e => { document.getElementById('welcomeButton').addEventListener('click', e => {
loginOptionsCancelEnabled(false) // False by default, be explicit. loginOptionsCancelEnabled(false) // False by default, be explicit.
loginOptionsViewOnLoginSuccess = VIEWS.library loginOptionsViewOnLoginSuccess = VIEWS.landing
loginOptionsViewOnLoginCancel = VIEWS.loginOptions loginOptionsViewOnLoginCancel = VIEWS.loginOptions
switchView(VIEWS.welcome, VIEWS.loginOptions) switchView(VIEWS.welcome, VIEWS.loginOptions)
}) })

View File

@@ -168,6 +168,14 @@ logoutFailed = "Failed to log out of the selected account. Please try again."
noSelection = "Select from Library" noSelection = "Select from Library"
loading = "Loading profile.." loading = "Loading profile.."
[js.landing.profileStatus]
label = "PROFILE"
[js.landing.mapStatus]
label = "STATUS"
ready = "READY TO RUN"
notReady = "SETUP REQUIRED"
[js.landing.selectedServer] [js.landing.selectedServer]
noSelection = "No Server Selected" noSelection = "No Server Selected"
loading = "Loading.." loading = "Loading.."

View File

@@ -168,6 +168,14 @@ logoutFailed = "계정을 로그아웃하지 못했습니다. 다시 시도해
noSelection = "라이브러리에서 선택" noSelection = "라이브러리에서 선택"
loading = "프로필 불러오는 중.." loading = "프로필 불러오는 중.."
[js.landing.profileStatus]
label = "프로필"
[js.landing.mapStatus]
label = "실행 상태"
ready = "실행 가능"
notReady = "실행 준비 필요"
[js.landing.selectedServer] [js.landing.selectedServer]
noSelection = "선택된 서버 없음" noSelection = "선택된 서버 없음"
loading = "로딩 중.." loading = "로딩 중.."

View File

@@ -9,10 +9,6 @@
<h2 class="launcherPageTitle"><%- lang('install.title') %></h2> <h2 class="launcherPageTitle"><%- lang('install.title') %></h2>
<p class="launcherPageSubtitle"><%- lang('install.subtitle') %></p> <p class="launcherPageSubtitle"><%- lang('install.subtitle') %></p>
</div> </div>
<div class="launcherPageActions">
<button id="installOpenSettingsButton" class="launcherSecondaryButton"><%- lang('library.settingsButton') %></button>
<button id="installBackToLibraryButton" class="launcherSecondaryButton"><%- lang('install.libraryPageButton') %></button>
</div>
</div> </div>
<div id="installCatalogNotice" class="launcherNotice"> <div id="installCatalogNotice" class="launcherNotice">
<span><%- lang('install.notice') %></span> <span><%- lang('install.notice') %></span>

View File

@@ -7,10 +7,6 @@
</div> </div>
</div> </div>
<div id="content"> <div id="content">
<div id="landingNavButtons">
<button id="landingLibraryButton" class="launcherSecondaryButton"><%- lang('landing.libraryButton') %></button>
<button id="landingInstallButton" class="launcherSecondaryButton"><%- lang('landing.installButton') %></button>
</div>
</div> </div>
<div id="right"> <div id="right">
<div id="rightContainer"> <div id="rightContainer">
@@ -165,15 +161,8 @@
<div class="bot_wrapper"> <div class="bot_wrapper">
<div id="content"> <div id="content">
<button id="newsButton"> <button id="newsButton">
<!--<img src="assets/images/icons/arrow.svg" id="newsButtonSVG"/>-->
<div id="newsButtonAlert" style="display: none;"></div> <div id="newsButtonAlert" style="display: none;"></div>
<svg id="newsButtonSVG" viewBox="0 0 24.87 13.97"> <span id="newsButtonText"><%- lang('landing.installButton') %></span>
<defs>
<style>.arrowLine{fill:none;stroke:#FFF;stroke-width:2px;}</style>
</defs>
<polyline class="arrowLine" points="0.71 13.26 12.56 1.41 24.16 13.02"/>
</svg>
&#10;<span id="newsButtonText"><%- lang('landing.newsButton') %></span>
</button> </button>
</div> </div>
</div> </div>
@@ -198,7 +187,7 @@
</div> </div>
</div> </div>
</div> </div>
<div id="newsContainer"> <div id="newsContainer" style="display: none;">
<div id="newsContent" article="-1" style="display: none;"> <div id="newsContent" article="-1" style="display: none;">
<div id="newsStatusContainer"> <div id="newsStatusContainer">
<div id="newsStatusContent"> <div id="newsStatusContent">

View File

@@ -9,11 +9,6 @@
<h2 class="launcherPageTitle"><%- lang('library.title') %></h2> <h2 class="launcherPageTitle"><%- lang('library.title') %></h2>
<p class="launcherPageSubtitle"><%- lang('library.subtitle') %></p> <p class="launcherPageSubtitle"><%- lang('library.subtitle') %></p>
</div> </div>
<div class="launcherPageActions">
<button id="libraryOpenSettingsButton" class="launcherSecondaryButton"><%- lang('library.settingsButton') %></button>
<button id="libraryOpenInstallButton" class="launcherSecondaryButton"><%- lang('library.installPageButton') %></button>
<button id="libraryOpenLaunchButton" class="launcherPrimaryButton"><%- lang('library.launchPageButton') %></button>
</div>
</div> </div>
<div id="libraryEmptyState" class="launcherEmptyState" style="display: none;"> <div id="libraryEmptyState" class="launcherEmptyState" style="display: none;">
<span class="launcherEmptyTitle"><%- lang('library.emptyTitle') %></span> <span class="launcherEmptyTitle"><%- lang('library.emptyTitle') %></span>