feat: update right widget and add new 3d widget

This commit is contained in:
2026-04-30 22:57:14 +03:00
parent 53b8ce7095
commit 7f8a327329
18 changed files with 217 additions and 80 deletions

14
.env
View File

@@ -1,8 +1,8 @@
# VITE_API_URL='https://wn.st.unprism.ru' VITE_API_URL='https://wn.st.unprism.ru'
# VITE_REACT_APP ='https://wn.st.unprism.ru/' VITE_REACT_APP ='https://wn.st.unprism.ru/'
# VITE_KRBL_MEDIA='https://wn.st.unprism.ru/media/' VITE_KRBL_MEDIA='https://wn.st.unprism.ru/media/'
# VITE_NEED_AUTH='true'
VITE_API_URL='https://wn.krbl.ru'
VITE_REACT_APP ='https://wn.krbl.ru/'
VITE_KRBL_MEDIA='https://wn.krbl.ru/media/'
VITE_NEED_AUTH='true' VITE_NEED_AUTH='true'
# VITE_API_URL='https://wn.krbl.ru'
# VITE_REACT_APP ='https://wn.krbl.ru/'
# VITE_KRBL_MEDIA='https://wn.krbl.ru/media/'
# VITE_NEED_AUTH='true'

View File

@@ -63,6 +63,7 @@ class ApiStore {
simulationDirection: 1 | -1 = 1; simulationDirection: 1 | -1 = 1;
simulationPaused = false; simulationPaused = false;
simulationInstantMove = false; simulationInstantMove = false;
showHitboxes = false;
constructor() { constructor() {
makeAutoObservable(this); makeAutoObservable(this);
@@ -191,6 +192,10 @@ class ApiStore {
this.simulationInstantMove = !this.simulationInstantMove; this.simulationInstantMove = !this.simulationInstantMove;
}; };
toggleShowHitboxes = () => {
this.showHitboxes = !this.showHitboxes;
};
startPositionSimulation = () => { startPositionSimulation = () => {
if (this.positionInterval) return; if (this.positionInterval) return;

View File

@@ -0,0 +1,3 @@
<svg width="15" height="14" viewBox="0 0 15 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.9941 5.96193C13.028 4.86487 12.0189 3.81 11.0097 2.73404C10.5374 2.2277 9.78591 2.14332 9.18473 2.50197C8.86267 2.69185 8.64796 2.98721 8.51914 3.32476C7.51002 2.33319 6.47943 1.42601 5.47031 0.434434C4.69737 -0.325069 3.47355 -0.0508043 3.10855 0.961866C3.10855 1.00406 3.08707 1.00406 3.0656 1.02516C2.65766 0.750893 2.18531 0.708699 1.69148 0.919672C1.11178 1.17284 0.811185 1.61588 0.789714 2.2488C0.789714 2.56526 0.897071 2.86062 1.06884 3.13489C0.746777 3.24038 0.489128 3.40915 0.295893 3.66232C-0.154991 4.25305 -0.09058 5.05474 0.489127 5.60327C2.16384 7.24886 3.83854 8.89445 5.53472 10.5611C5.57767 10.6033 5.62061 10.6455 5.68502 10.7088C5.66355 10.7088 5.64208 10.7088 5.62061 10.7088C4.63296 10.8565 3.62384 11.0253 2.63619 11.173C1.88472 11.2784 1.3909 11.6793 1.17619 12.3966C0.918542 13.2405 1.43383 14 2.29266 14C4.71884 14 7.12355 14 9.54973 14C10.7091 14 11.6968 13.5992 12.5127 12.7975C12.9421 12.3755 13.3715 11.9536 13.8009 11.5316C15.3253 9.99151 15.4112 7.56532 13.9727 5.94083L13.9941 5.96193ZM13.2212 11.0675C12.8133 11.4683 12.4053 11.8692 11.9974 12.27C11.3103 12.924 10.4944 13.2616 9.52826 13.2616C8.36885 13.2616 7.18796 13.2616 6.02855 13.2616C4.86913 13.2616 3.60236 13.2616 2.37854 13.2616C1.99207 13.2616 1.82031 13.0506 1.92766 12.692C2.01354 12.2911 2.3356 12.0169 2.76501 11.9536C4.01031 11.7637 5.27708 11.5738 6.52237 11.3839C6.69414 11.3628 6.84443 11.2995 6.88737 11.1308C6.95178 10.9409 6.88737 10.7932 6.73708 10.6666C4.84767 8.81006 2.95825 6.9535 1.06884 5.09694C0.83266 4.86487 0.746777 4.6117 0.85413 4.31634C1.00442 3.87329 1.56266 3.72561 1.94913 3.99988C2.01354 4.04207 2.05648 4.10536 2.1209 4.14756C3.34472 5.35011 4.59001 6.57375 5.81384 7.77629C5.92119 7.88178 6.02855 7.96617 6.17884 7.94507C6.47943 7.94507 6.62972 7.60752 6.47943 7.37545C6.43649 7.31215 6.37208 7.24886 6.32914 7.20667C4.84767 5.72986 3.34472 4.27414 1.84177 2.81843C1.64854 2.62855 1.54119 2.39648 1.6056 2.12222C1.73443 1.61588 2.3356 1.42601 2.74354 1.76356C2.78648 1.80576 2.82943 1.84795 2.89384 1.89015C4.35384 3.32476 5.83532 4.78048 7.29532 6.2151C7.33826 6.25729 7.35973 6.29948 7.40267 6.32058C7.57444 6.46826 7.81061 6.48936 7.9609 6.32058C8.1112 6.1729 8.1112 5.94083 7.9609 5.77205C7.72473 5.53998 7.25237 5.07584 7.25237 5.07584L6.24325 4.08427C6.24325 4.08427 5.49178 3.34586 5.12678 2.98721C4.76178 2.62855 4.41825 2.291 4.05325 1.93234C3.88149 1.74247 3.77413 1.55259 3.83855 1.27833C3.9459 0.814185 4.50413 0.62431 4.89061 0.919672C4.95502 0.961866 4.99796 1.02516 5.0409 1.06735C6.1359 2.14332 7.25238 3.11379 8.34738 4.18975C8.54061 4.37963 8.71238 4.56951 8.90561 4.73828C9.09885 4.92816 9.33502 4.94926 9.50679 4.80158C9.67855 4.65389 9.65708 4.42182 9.46385 4.21085C9.18473 3.89439 9.2062 3.47245 9.50679 3.21928C9.80738 2.96611 10.2368 2.98721 10.5159 3.28257C11.4606 4.29524 12.4053 5.32901 13.35 6.34168C14.5953 7.713 14.5524 9.73834 13.2427 11.0464L13.2212 11.0675Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,3 @@
<svg width="15" height="12" viewBox="0 0 15 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.993 3.76793C13.0258 2.64439 12.0155 1.56407 11.0053 0.462135C10.5324 -0.0564207 9.78007 -0.142847 9.17822 0.224464C8.8558 0.418922 8.64085 0.721413 8.51188 1.06712C7.69509 0.505348 6.57737 0.786232 6.19046 1.82334C6.19046 1.82334 6.19046 1.82334 6.19046 1.88816C5.78206 1.62889 5.33068 1.60728 4.85779 1.82334C4.40641 2.0178 4.14847 2.3419 4.0195 2.75242C3.6326 2.36351 2.60085 1.348 2.47189 1.21836C2.0205 0.786232 1.46164 0.699806 0.902776 0.959084C0.773808 1.0023 0.687829 1.06712 0.580356 1.15354C0.365409 1.30479 0.236441 1.49925 0.128968 1.73692C0.128968 1.78013 0.107473 1.82334 0.0859786 1.86656C0 1.9962 0 2.14744 0 2.29869C0 2.53636 0.064484 2.75242 0.150463 2.96849C0.150463 2.96849 0.343915 3.27098 0.472883 3.40062C2.14947 5.08592 3.82605 6.77123 5.52413 8.47814C5.56712 8.52135 5.61011 8.56457 5.67459 8.62939C5.6531 8.62939 5.6316 8.62939 5.61011 8.62939C4.62135 8.78063 3.6111 8.95348 2.62235 9.10473C1.87004 9.21276 1.37566 9.62329 1.16071 10.3579C0.902776 11.2222 1.41865 12 2.27843 12C4.70733 12 7.11473 12 9.54363 12C10.7043 12 11.6931 11.5895 12.5099 10.7684C12.9398 10.3363 13.3697 9.90417 13.7996 9.47204C15.3257 7.89477 15.4117 5.41002 13.9715 3.74632L13.993 3.76793ZM13.2192 8.9967C12.8108 9.40722 12.4024 9.81774 11.994 10.2283C11.3062 10.8981 10.4894 11.2438 9.52213 11.2438C8.36142 11.2438 7.17922 11.2438 6.0185 11.2438C4.85779 11.2438 3.58961 11.2438 2.36441 11.2438C1.97751 11.2438 1.80555 11.0277 1.91302 10.6604C1.999 10.2499 2.32142 9.96899 2.75132 9.90417C3.99801 9.70971 5.26619 9.51525 6.51288 9.3208C6.68484 9.29919 6.8353 9.23437 6.87829 9.06152C6.94278 8.86706 6.87829 8.71581 6.72783 8.58617C4.8363 6.6848 2.94477 4.78343 1.05324 2.88206C0.92427 2.75242 0.838292 2.60118 0.795302 2.44993C0.795302 2.44993 0.795302 2.40672 0.795302 2.38511C0.795302 2.38511 0.795302 2.3419 0.795302 2.32029C0.795302 2.27708 0.795302 2.23387 0.795302 2.16905C0.795302 2.16905 0.795302 2.14744 0.795302 2.12583C0.795302 2.10423 0.795302 2.08262 0.816797 2.06101C0.816797 2.03941 0.838292 1.9962 0.859786 1.97459C1.07473 1.60728 1.56911 1.49925 1.93452 1.80174C1.97751 1.84495 2.0205 1.88816 2.08498 1.93138C3.05224 2.90367 4.0195 3.87596 4.98676 4.84825C5.2447 5.10753 5.52413 5.38841 5.78206 5.64769C5.88954 5.75572 5.99701 5.84215 6.14747 5.82054C6.4484 5.82054 6.59886 5.47484 6.4484 5.23717C6.40541 5.17235 6.34092 5.10753 6.29794 5.06432C5.84655 4.61058 5.37366 4.13524 4.92228 3.6815C4.77181 3.50865 4.70733 3.29258 4.77181 3.05491C4.90078 2.53636 5.50263 2.3419 5.91103 2.6876C5.95402 2.73082 5.99701 2.77403 6.06149 2.81724C6.38391 3.14134 6.68484 3.44383 7.00726 3.76793C7.09324 3.85435 7.17922 3.94078 7.28669 4.04881C7.32968 4.09202 7.35117 4.13524 7.39416 4.15684C7.56612 4.30809 7.80256 4.3297 7.95302 4.15684C8.10349 4.0056 8.10349 3.76793 7.95302 3.59508C7.80256 3.44383 7.6521 3.27098 7.48014 3.11973C7.35117 2.99009 7.2437 2.88206 7.11473 2.75242C6.8568 2.42833 6.92128 2.0178 7.15772 1.78013C7.45865 1.47764 7.86705 1.49925 8.23245 1.86656C8.4689 2.10423 8.68384 2.32029 8.92028 2.55796C9.11374 2.75242 9.35018 2.77403 9.52213 2.62278C9.69409 2.47154 9.6726 2.23387 9.47915 2.0178C9.19971 1.6937 9.22121 1.26158 9.52213 1.0023C9.82306 0.743019 10.253 0.764626 10.5324 1.06712C11.4781 2.10423 12.4239 3.16295 13.3697 4.20006C14.6164 5.60448 14.5734 7.6787 13.2622 9.0183L13.2192 8.9967Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,3 @@
<svg width="15" height="13" viewBox="0 0 15 13" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.67979 9.7487C5.63689 9.68658 5.57254 9.64516 5.52964 9.60374C3.85647 7.98845 2.16185 6.37316 0.488679 4.73716C-0.0904948 4.17802 -0.154849 3.41179 0.295619 2.83194C0.488677 2.58343 0.746089 2.41776 1.06785 2.31422C0.896245 2.045 0.767539 1.77579 0.78899 1.44444C0.78899 0.823178 1.11075 0.388292 1.68993 0.139785C2.2691 -0.108722 2.80537 -0.0258861 3.25584 0.388291C3.87792 0.96814 4.47854 1.5687 5.07917 2.14855C5.44383 2.5006 5.8085 2.85265 6.19461 3.22541C6.58073 2.23138 7.69618 1.94146 8.51131 2.5006C8.64001 2.14855 8.85452 1.87933 9.17629 1.69295C9.77691 1.3409 10.5277 1.42374 10.9996 1.92075C12.0078 2.9769 13.016 4.01235 13.9813 5.08921C15.4185 6.68379 15.3112 9.06531 13.8097 10.5771C13.3807 10.9912 12.9516 11.4054 12.5226 11.8196C11.7075 12.5858 10.7207 12.9793 9.5624 13C7.13845 13 4.73595 13 2.312 13C1.45397 13 0.917694 12.2752 1.19656 11.4261C1.41106 10.722 1.92589 10.3493 2.65522 10.225C3.64196 10.08 4.65015 9.91438 5.63689 9.76941C5.63689 9.76941 5.65834 9.76941 5.70124 9.76941L5.67979 9.7487ZM6.023 12.2545C7.18135 12.2545 8.36115 12.2545 9.5195 12.2545C10.4848 12.2545 11.2999 11.9231 11.9864 11.2812C12.3939 10.8877 12.8015 10.4942 13.2091 10.1008C14.5176 8.81681 14.5819 6.82875 13.3163 5.48268C12.3725 4.46794 11.4286 3.47391 10.4848 2.47989C10.2059 2.18996 9.77691 2.14855 9.4766 2.41776C9.17629 2.68698 9.15484 3.10115 9.4337 3.39108C9.62675 3.59817 9.62675 3.80526 9.4766 3.97093C9.30499 4.11589 9.09048 4.09518 8.87597 3.9088C8.64001 3.70171 8.4255 3.47391 8.18955 3.24612C7.84633 2.91477 7.41731 2.87336 7.117 3.16328C6.85959 3.41179 6.79524 3.86738 7.18135 4.19873C7.43877 4.40581 7.65327 4.65432 7.88923 4.88212C8.06084 5.04779 8.06084 5.27559 7.88923 5.42055C7.73908 5.56551 7.50312 5.56551 7.33151 5.42055C7.28861 5.37913 7.24571 5.33771 7.22426 5.317C5.7656 3.9088 4.28548 2.47989 2.82682 1.07168C2.78392 1.03027 2.74102 0.988849 2.67667 0.947431C2.2691 0.616089 1.66848 0.802469 1.53977 1.29948C1.47542 1.5687 1.58267 1.7965 1.77573 1.98288C3.27729 3.41179 4.7574 4.86141 6.25897 6.29032C6.32332 6.35245 6.36622 6.39387 6.40912 6.45599C6.55928 6.7045 6.40912 6.99442 6.10881 7.01513C5.95865 7.01513 5.8514 6.9323 5.74415 6.84946C4.52145 5.66906 3.27729 4.46794 2.05459 3.28753C1.99024 3.22541 1.94734 3.18399 1.88299 3.14257C1.49687 2.87336 0.960597 3.01832 0.78899 3.45321C0.681736 3.76384 0.78899 4.01235 1.0035 4.21943C2.89118 6.04182 4.77885 7.8642 6.66653 9.68658C6.79524 9.81083 6.88104 9.95579 6.81669 10.1422C6.75234 10.3078 6.62363 10.37 6.45202 10.3907C5.20787 10.5771 3.94227 10.7634 2.69812 10.9498C2.2691 11.0119 1.96879 11.2812 1.86153 11.6746C1.77573 12.0474 1.92589 12.2338 2.312 12.2338C3.5347 12.2338 4.73595 12.2338 5.95865 12.2338L6.023 12.2545Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -16,6 +16,9 @@ import { ThreeViewErrorBoundary } from "../ThreeViewErrorBoundary";
import { apiStore } from "../../api/ApiStore/store"; import { apiStore } from "../../api/ApiStore/store";
import { ReactMarkdownComponent } from "../ReactMarkdown"; import { ReactMarkdownComponent } from "../ReactMarkdown";
import { TouchableLayout } from "../TouchableLayout"; import { TouchableLayout } from "../TouchableLayout";
import rotate3DIcon from "../../assets/icons/three-view-rotate.svg";
import zoom3DIcon from "../../assets/icons/three-view-zoom.svg";
import pan3DIcon from "../../assets/icons/three-view-pan.svg";
const Watermark = ({ path }) => { const Watermark = ({ path }) => {
if (!path) return null; if (!path) return null;
@@ -364,6 +367,87 @@ const SightFrame = observer(({ media, sight_id, sight_name }) => {
/> />
</svg> </svg>
</button> </button>
{isFullscreen3D && <div
style={{
position: "absolute",
top: 94,
right: 10,
zIndex: 10,
pointerEvents: "none",
}}
>
<div
className="cluster-sights-list"
style={{
background: `linear-gradient(to bottom right, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 100%), rgba(179, 165, 152, 0.4)`,
backdropFilter: "blur(10px)",
borderRadius: "8px",
width: 200,
boxShadow:
"0 0 0 1px rgba(255, 255, 255, 0.3) inset, 4px 4px 12px 0 rgba(255, 255, 255, 0.12) inset",
display: "flex",
flexDirection: "column",
padding: "8px 13px",
}}
>
{[
{
label: "Вращать",
icon: <img src={rotate3DIcon} alt="" width="14" height="14" />,
},
{
label: "Приблизить / Отдалить",
icon: <img src={zoom3DIcon} alt="" width="14" height="14" />,
},
{
label: "Переместить",
icon: <img src={pan3DIcon} alt="" width="14" height="14" />,
},
].map((item, index, arr) => (
<div
key={index}
style={{
display: "flex",
alignItems: "center",
height: "30px",
userSelect: "none",
touchAction: "none",
padding: "0 4px",
borderBottom:
index < arr.length - 1
? "1px solid rgba(255, 255, 255, 0.1)"
: "none",
transition: "background-color 0.2s",
}}
>
<span
style={{
display: "block",
marginRight: "8px",
flexShrink: 0,
lineHeight: 0,
}}
>
{item.icon}
</span>
<span
style={{
color: "white",
fontSize: "12px",
lineHeight: "1.5",
fontWeight: "400",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
flex: 1,
}}
>
{item.label}
</span>
</div>
))}
</div>
</div>}
</div> </div>
); );
default: default:
@@ -464,7 +548,7 @@ const SightFrame = observer(({ media, sight_id, sight_name }) => {
const titleLineHeight = useMemo(() => { const titleLineHeight = useMemo(() => {
if (!sight_name) return "120%"; if (!sight_name) return "120%";
const textLength = sight_name.length; const textLength = sight_name.replace(/\n/g, "").length;
const calculatedLineHeight = Math.max( const calculatedLineHeight = Math.max(
100, 100,
Math.min(120, 120 - (textLength / 10) * 1), Math.min(120, 120 - (textLength / 10) * 1),
@@ -520,7 +604,7 @@ const SightFrame = observer(({ media, sight_id, sight_name }) => {
overflowWrap: "break-word", overflowWrap: "break-word",
}} }}
> >
{selectedSection === 0 ? processedSightName : sight_name} {selectedSection === 0 ? processedSightName : (sightData?.short_name || sight_name)}
</p> </p>
</div> </div>
)} )}
@@ -552,7 +636,7 @@ const SightFrame = observer(({ media, sight_id, sight_name }) => {
paddingBottom: "4.5px", paddingBottom: "4.5px",
cursor: "pointer", cursor: "pointer",
}} }}
onPointerUp={() => setSelectedSection(0)} onPointerUp={() => { setSelectedSection(0); setIsFullscreen3D(false); }}
> >
<svg <svg
width="20" width="20"
@@ -599,7 +683,7 @@ const SightFrame = observer(({ media, sight_id, sight_name }) => {
articleSections.length > 1 && articleSections.length > 1 &&
articleSections.slice(1).map((section, index) => ( articleSections.slice(1).map((section, index) => (
<div <div
onPointerUp={() => setSelectedSection(index + 1)} onPointerUp={() => { setSelectedSection(index + 1); setIsFullscreen3D(false); }}
key={section.id || section.heading || index} key={section.id || section.heading || index}
className={`sight-frame-menu-point ${ className={`sight-frame-menu-point ${
index + 1 === selectedSection ? "active" : "" index + 1 === selectedSection ? "active" : ""

View File

@@ -80,6 +80,15 @@ export const SimulationSettings = observer(() => {
onClick={apiStore.toggleSimulationInstantMove} onClick={apiStore.toggleSimulationInstantMove}
/> />
</Row> </Row>
{/* Хитбоксы */}
<Row>
<span>Хитбоксы</span>
<Toggle
on={apiStore.showHitboxes}
onClick={apiStore.toggleShowHitboxes}
/>
</Row>
</div> </div>
)} )}
</div> </div>

View File

@@ -797,9 +797,8 @@ export const WebGLMap = observer(() => {
const textBlockPositionX = rx + labelOffsetX; const textBlockPositionX = rx + labelOffsetX;
const textBlockPositionY = ry + labelOffsetY; const textBlockPositionY = ry + labelOffsetY;
const nameLines = st.name.replace(/\\n/g, '\n').split('\n'); const normalizedName = st.name.replace(/\\n|\n/g, "");
const longestLine = nameLines.reduce((a: string, b: string) => a.length > b.length ? a : b, ''); const approximateTextWidth = normalizedName.length * fontSize * 0.6;
const approximateTextWidth = longestLine.length * fontSize * 0.6;
const textWidthInMapCoords = approximateTextWidth / scale; const textWidthInMapCoords = approximateTextWidth / scale;
let anchorXOffset = 0; let anchorXOffset = 0;
@@ -829,8 +828,8 @@ export const WebGLMap = observer(() => {
result.push({ result.push({
x: sx, x: sx,
y: sy, y: sy,
name: st.name.replace(/\\n/g, '\n'), name: normalizedName,
sub: sub ? sub.replace(/\\n/g, '\n') : sub, sub: sub ? sub.replace(/\\n|\n/g, "") : sub,
anchorX: anchorX, anchorX: anchorX,
anchorY: anchorY, anchorY: anchorY,
distance: distanceInPixels, distance: distanceInPixels,
@@ -2315,7 +2314,7 @@ export const WebGLMap = observer(() => {
fontSize: primaryFontSize, fontSize: primaryFontSize,
textShadow: "0 0 4px rgba(0,0,0,0.6)", textShadow: "0 0 4px rgba(0,0,0,0.6)",
pointerEvents: "none", pointerEvents: "none",
whiteSpace: "pre-line", whiteSpace: "nowrap",
}} }}
> >
{l.name} {l.name}
@@ -2331,7 +2330,7 @@ export const WebGLMap = observer(() => {
lineHeight: secondaryLineHeight, lineHeight: secondaryLineHeight,
color: "#CBCBCB", color: "#CBCBCB",
textShadow: "0 0 3px rgba(0,0,0,0.4)", textShadow: "0 0 3px rgba(0,0,0,0.4)",
whiteSpace: "pre-line", whiteSpace: "nowrap",
...secondaryPositionStyle, ...secondaryPositionStyle,
pointerEvents: "none", pointerEvents: "none",
}} }}
@@ -2417,6 +2416,11 @@ export const WebGLMap = observer(() => {
cursor: "pointer", cursor: "pointer",
userSelect: "none", userSelect: "none",
touchAction: "none", touchAction: "none",
...(apiStore.showHitboxes && {
outline: "2px solid rgba(0,255,0,0.8)",
outlineOffset: "2px",
backgroundColor: "rgba(0,255,0,0.08)",
}),
}} }}
> >
<div <div
@@ -2553,6 +2557,11 @@ export const WebGLMap = observer(() => {
userSelect: "none", userSelect: "none",
touchAction: "none", touchAction: "none",
zIndex: 10, zIndex: 10,
...(apiStore.showHitboxes && {
outline: "2px solid rgba(255,165,0,0.8)",
outlineOffset: "2px",
backgroundColor: "rgba(255,165,0,0.08)",
}),
}} }}
> >
<div style={{ position: "relative" }}> <div style={{ position: "relative" }}>
@@ -2608,6 +2617,11 @@ export const WebGLMap = observer(() => {
alignItems: "flex-start", alignItems: "flex-start",
pointerEvents: "auto", pointerEvents: "auto",
zIndex: 100000000000000, zIndex: 100000000000000,
...(apiStore.showHitboxes && {
outline: "2px solid rgba(0,180,255,0.8)",
outlineOffset: "2px",
backgroundColor: "rgba(0,180,255,0.08)",
}),
}} }}
> >
<div <div

View File

@@ -143,9 +143,9 @@ export const CityCreatePage = observer(() => {
<TextField <TextField
fullWidth fullWidth
label="Код города для погоды" label="Код города для погоды"
type="number"
value={createCityData.weather_city_code ?? 0} value={createCityData.weather_city_code ?? 0}
onChange={(e) => setCreateCityWeatherCode(Number(e.target.value))} onChange={(e) => setCreateCityWeatherCode(Number(e.target.value))}
helperText="ID города брать с ресурса openweathermap.org"
/> />
<div className="w-full flex flex-col gap-4 max-w-[300px] mx-auto"> <div className="w-full flex flex-col gap-4 max-w-[300px] mx-auto">

View File

@@ -189,9 +189,9 @@ export const CityEditPage = observer(() => {
<TextField <TextField
fullWidth fullWidth
label="Код города для погоды" label="Код города для погоды"
type="number"
value={editCityData.weather_city_code ?? 0} value={editCityData.weather_city_code ?? 0}
onChange={(e) => setEditCityWeatherCode(Number(e.target.value))} onChange={(e) => setEditCityWeatherCode(Number(e.target.value))}
helperText="ID города брать с ресурса openweathermap.org"
/> />
<div className="w-full flex flex-col gap-4 max-w-[300px] mx-auto"> <div className="w-full flex flex-col gap-4 max-w-[300px] mx-auto">

View File

@@ -205,7 +205,7 @@ export const CreateInformationTab = observer(
> >
<div className="flex gap-10 items-center mb-5 max-w-[80%]"> <div className="flex gap-10 items-center mb-5 max-w-[80%]">
<BackButton /> <BackButton />
<h1 className="text-3xl break-words">{sight[language].name}</h1> <h1 className="text-3xl break-words">{sight[language].name.replace(/\n/g, " ")}</h1>
</div> </div>
<Box <Box

View File

@@ -94,7 +94,7 @@ export const CreateLeftTab = observer(
> >
<div className="flex gap-10 items-center mb-5 max-w-[80%]"> <div className="flex gap-10 items-center mb-5 max-w-[80%]">
<BackButton /> <BackButton />
<h1 className="text-3xl break-words">{sight[language].name}</h1> <h1 className="text-3xl break-words">{sight[language].name.replace(/\n/g, " ")}</h1>
</div> </div>
<Paper <Paper
elevation={2} elevation={2}

View File

@@ -231,7 +231,7 @@ export const CreateRightTab = observer(
> >
<div className="flex gap-10 items-center mb-5 max-w-[80%]"> <div className="flex gap-10 items-center mb-5 max-w-[80%]">
<BackButton /> <BackButton />
<h1 className="text-3xl break-words">{sight[language].name}</h1> <h1 className="text-3xl break-words">{sight[language].name.replace(/\n/g, " ")}</h1>
</div> </div>
<Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}> <Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}>
@@ -508,36 +508,44 @@ export const CreateRightTab = observer(
/> />
</Stack> </Stack>
)} )}
<Stack direction="row" spacing={1} alignItems="flex-start"> {type === "media" && (
<TextField <Stack direction="row" spacing={1} alignItems="flex-start">
label="Полное название (поддерживает перенос ↵)" <TextField
multiline label="Полное название (поддерживает перенос ↵)"
minRows={1} multiline
maxRows={4} minRows={1}
size="small" maxRows={4}
value={sight[language].name} size="small"
onChange={(e) => value={sight[language].name}
updateSightInfo({ name: e.target.value }, language) onChange={(e) =>
} updateSightInfo({ name: e.target.value }, language)
inputRef={shortNameRef} }
sx={{ flexGrow: 1 }} onKeyDown={(e) => {
/> if (e.key === "Enter") {
<Button e.preventDefault();
variant="outlined" insertNewline();
size="small" }
onClick={insertNewline} }}
title="Вставить перенос строки" inputRef={shortNameRef}
sx={{ sx={{ flexGrow: 1 }}
minWidth: 40, />
height: 40, <Button
fontSize: 18, variant="outlined"
p: 0, size="small"
flexShrink: 0, onClick={insertNewline}
}} title="Вставить перенос строки"
> sx={{
minWidth: 40,
</Button> height: 40,
</Stack> fontSize: 18,
p: 0,
flexShrink: 0,
}}
>
</Button>
</Stack>
)}
<SightFramePreview <SightFramePreview
sightName={sight[language].name} sightName={sight[language].name}
previewMedia={previewMedia} previewMedia={previewMedia}

View File

@@ -207,7 +207,7 @@ export const InformationTab = observer(
> >
<div className="flex gap-10 items-center mb-5 max-w-[80%]"> <div className="flex gap-10 items-center mb-5 max-w-[80%]">
<BackButton /> <BackButton />
<h1 className="text-3xl break-words">{sight[language].name}</h1> <h1 className="text-3xl break-words">{sight[language].name.replace(/\n/g, " ")}</h1>
</div> </div>
<LanguageSwitcher /> <LanguageSwitcher />

View File

@@ -112,7 +112,7 @@ export const LeftWidgetTab = observer(
> >
<div className="flex gap-10 items-center mb-5 max-w-[80%]"> <div className="flex gap-10 items-center mb-5 max-w-[80%]">
<BackButton /> <BackButton />
<h1 className="text-3xl break-words">{sight[language].name}</h1> <h1 className="text-3xl break-words">{sight[language].name.replace(/\n/g, " ")}</h1>
</div> </div>
<Paper <Paper

View File

@@ -213,7 +213,7 @@ export function SightFramePreview({
if (!sightName) return "120%"; if (!sightName) return "120%";
const calculatedLineHeight = Math.max( const calculatedLineHeight = Math.max(
100, 100,
Math.min(120, 120 - (sightName.length / 10) * 1) Math.min(120, 120 - (sightName.replace(/\n/g, "").length / 10) * 1)
); );
return `${calculatedLineHeight}%`; return `${calculatedLineHeight}%`;
}, [sightName]); }, [sightName]);

View File

@@ -201,7 +201,7 @@ export const RightWidgetTab = observer(
> >
<div className="flex gap-10 items-center mb-5 max-w-[80%]"> <div className="flex gap-10 items-center mb-5 max-w-[80%]">
<BackButton /> <BackButton />
<h1 className="text-3xl break-words">{sight[language].name}</h1> <h1 className="text-3xl break-words">{sight[language].name.replace(/\n/g, " ")}</h1>
</div> </div>
<Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}> <Box sx={{ display: "flex", flexGrow: 1, gap: 2.5 }}>
@@ -476,28 +476,36 @@ export const RightWidgetTab = observer(
/> />
</Stack> </Stack>
)} )}
<Stack direction="row" spacing={1} alignItems="flex-start"> {type === "media" && (
<TextField <Stack direction="row" spacing={1} alignItems="flex-start">
label="Полное название (поддерживает перенос ↵)" <TextField
multiline label="Полное название (поддерживает перенос ↵)"
minRows={1} multiline
maxRows={4} minRows={1}
size="small" maxRows={4}
value={sight[language].name} size="small"
onChange={(e) => updateSightInfo(language, { name: e.target.value })} value={sight[language].name}
inputRef={shortNameRef} onChange={(e) => updateSightInfo(language, { name: e.target.value })}
sx={{ flexGrow: 1 }} onKeyDown={(e) => {
/> if (e.key === "Enter") {
<Button e.preventDefault();
variant="outlined" insertNewline();
size="small" }
onClick={insertNewline} }}
title="Вставить перенос строки" inputRef={shortNameRef}
sx={{ minWidth: 40, height: 40, fontSize: 18, p: 0, flexShrink: 0 }} sx={{ flexGrow: 1 }}
> />
<Button
</Button> variant="outlined"
</Stack> size="small"
onClick={insertNewline}
title="Вставить перенос строки"
sx={{ minWidth: 40, height: 40, fontSize: 18, p: 0, flexShrink: 0 }}
>
</Button>
</Stack>
)}
<SightFramePreview <SightFramePreview
sightName={sight[language].name} sightName={sight[language].name}
previewMedia={previewMedia} previewMedia={previewMedia}

File diff suppressed because one or more lines are too long