index.mstemplate.html 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8" />
  5. <title>
  6. {{#IF isInReportingMode}}
  7. {{/IF}}
  8. Jellyfin Startup
  9. </title>
  10. <style>
  11. * {
  12. font-family: sans-serif;
  13. }
  14. .flex-row {
  15. display: flex;
  16. flex-direction: row;
  17. flex-wrap: nowrap;
  18. justify-content: center;
  19. align-items: center;
  20. align-content: normal;
  21. }
  22. .flex-col {
  23. display: flex;
  24. flex-direction: column;
  25. flex-wrap: nowrap;
  26. justify-content: center;
  27. align-items: center;
  28. align-content: normal;
  29. }
  30. header {
  31. height: 5rem;
  32. width: 100%;
  33. }
  34. header svg {
  35. height: 3rem;
  36. width: 9rem;
  37. margin-right: 1rem;
  38. }
  39. /* ol.action-list {
  40. list-style-type: none;
  41. position: relative;
  42. } */
  43. ol.action-list * {
  44. font-family: monospace;
  45. font-weight: 300;
  46. font-size: clamp(18px, 100vw / var(--width), 20px);
  47. font-feature-settings: 'onum', 'pnum';
  48. line-height: 1.8;
  49. -webkit-text-size-adjust: none;
  50. }
  51. /*
  52. ol.action-list li {
  53. padding-top: .5rem;
  54. }
  55. ol.action-list li::before {
  56. position: absolute;
  57. left: -0.8em;
  58. font-size: 1.1em;
  59. } */
  60. /* Attribution as heavily inspired by: https://iamkate.com/code/tree-views/ */
  61. .action-list {
  62. --spacing: 1.4rem;
  63. --radius: 14px;
  64. }
  65. .action-list li {
  66. display: block;
  67. position: relative;
  68. padding-left: calc(2 * var(--spacing) - var(--radius) - 1px);
  69. }
  70. .action-list ul {
  71. margin-left: calc(var(--radius) - var(--spacing));
  72. padding-left: 0;
  73. }
  74. .action-list ul li {
  75. border-left: 2px solid #ddd;
  76. }
  77. .action-list ul li:last-child {
  78. border-color: transparent;
  79. }
  80. .action-list ul li::before {
  81. content: '';
  82. display: block;
  83. position: absolute;
  84. top: calc(var(--spacing) / -2);
  85. left: -2px;
  86. width: calc(var(--spacing) + 2px);
  87. height: calc(var(--spacing) + 1px);
  88. border: solid #ddd;
  89. border-width: 0 0 2px 2px;
  90. }
  91. .action-list summary {
  92. display: block;
  93. cursor: pointer;
  94. }
  95. .action-list summary::marker,
  96. .action-list summary::-webkit-details-marker {
  97. display: none;
  98. }
  99. .action-list summary:focus {
  100. outline: none;
  101. }
  102. .action-list summary:focus-visible {
  103. outline: 1px dotted #000;
  104. }
  105. .action-list li::after,
  106. .action-list summary::before {
  107. content: '';
  108. display: block;
  109. position: absolute;
  110. top: calc(var(--spacing) / 2 - var(--radius) + 4px);
  111. left: calc(var(--spacing) - var(--radius) - -5px);
  112. }
  113. .action-list summary::before {
  114. z-index: 1;
  115. /* background: #696 url('expand-collapse.svg') 0 0; */
  116. }
  117. .action-list details[open]>summary::before {
  118. background-position: calc(-2 * var(--radius)) 0;
  119. }
  120. .action-list li.danger-item::after,
  121. .action-list li.danger-strong-item::after {
  122. content: '❌';
  123. }
  124. ol.action-list li span.danger-strong-item {
  125. text-decoration-style: solid;
  126. text-decoration-color: red;
  127. text-decoration-line: underline;
  128. }
  129. ol.action-list li.warn-item::after {
  130. content: '⚠️';
  131. }
  132. ol.action-list li.success-item::after {
  133. content: '✅';
  134. }
  135. ol.action-list li.info-item::after {
  136. content: '🔹';
  137. }
  138. /* End Attribution */
  139. </style>
  140. </head>
  141. <body>
  142. <div>
  143. <header class="flex-row">
  144. {{^IF isInReportingMode}}
  145. <p>Jellyfin Server still starting. Please wait.</p>
  146. {{#ELSE}}
  147. <p>Jellyfin Server has encountered an error and was not able to start.</p>
  148. {{/ELSE}}
  149. {{/IF}}
  150. {{#IF localNetworkRequest}}
  151. <p style="margin-left: 1rem;">You can download the current log file <a href='/startup/logger'
  152. target="_blank">here</a>.</p>
  153. {{/IF}}
  154. </header>
  155. {{#DECLARE LogEntry |--}}
  156. {{#LET children = Children}}
  157. <li class="{{FormatLogLevel(children).ToString()}}-item">
  158. {{--| #IF children.Count > 0}}
  159. <details open>
  160. <summary>{{DateOfCreation}} - {{Content}}</summary>
  161. <ul class="action-list">
  162. {{--| #EACH children.Reverse() |-}}
  163. {{#IMPORT 'LogEntry'}}
  164. {{--| /EACH |-}}
  165. </ul>
  166. </details>
  167. {{--| #ELSE |-}}
  168. <span class="{{FormatLogLevel(children).ToString()}}-item">{{DateOfCreation}} - {{Content}}</span>
  169. {{--| /ELSE |--}}
  170. {{--| /IF |-}}
  171. </li>
  172. {{--| /DECLARE}}
  173. {{#IF localNetworkRequest}}
  174. <div class="flex-col">
  175. <ol class="action-list">
  176. {{#FOREACH log IN logs.Reverse()}}
  177. {{#IMPORT 'LogEntry' #WITH log}}
  178. {{/FOREACH}}
  179. </ol>
  180. </div>
  181. {{#ELSE}}
  182. <p>Please visit this page from your local network to view detailed startup logs.</p>
  183. {{/ELSE}}
  184. {{/IF}}
  185. </div>
  186. </body>
  187. {{^IF isInReportingMode}}
  188. <script>
  189. setTimeout(() => {
  190. window.location.reload();
  191. }, {{ retryValue.TotalMilliseconds }});
  192. </script>
  193. {{/IF}}
  194. </html>