Compare commits
	
		
			52 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 163cf49f16 | ||
|   | c38a32dee9 | ||
|   | 4f5abed70d | ||
|   | c9ac9923df | ||
|   | bb14895fd8 | ||
|   | 6f92d601ec | ||
|   | 345143b0c1 | ||
|   | dc80d5d376 | ||
|   | d3544f9637 | ||
|   | 864b6ad1bd | ||
|   | c58027e521 | ||
|   | 10fb399588 | ||
|   | 10f466c895 | ||
|   | 32068b4bcc | ||
|   | 8bc5febe66 | ||
|   | 20335e23f9 | ||
|   | fe707f88a4 | ||
|   | 9b23ebd4a3 | ||
|   | bea450cc2c | ||
|   | e80709f7aa | ||
| ![imgbot[bot]](/assets/img/avatar_default.png)  | cb71f92f42 | ||
|   | 2ca5348560 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | c8e98fdf8e | ||
|   | 0bfa041026 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 33bf474a1e | ||
|   | 53c559c001 | ||
| ![dependabot[bot]](/assets/img/avatar_default.png)  | 1c99ef454b | ||
|   | cf4cecd4df | ||
|   | 6a8835b923 | ||
|   | f2b1cf92e1 | ||
|   | 6b79618e74 | ||
|   | 3db414add4 | ||
|   | 9ef641b403 | ||
|   | 6fa7819a44 | ||
|   | 59a1b9adbe | ||
|   | 3fbc7094f6 | ||
|   | 56c6227bc2 | ||
|   | ee82f99f5a | ||
|   | 789de130a2 | ||
|   | 46c026ce70 | ||
|   | 82290f6e4e | ||
|   | 8729525f95 | ||
|   | df0115ffe8 | ||
|   | 0275b4fc9e | ||
|   | 9982fd71ba | ||
|   | 081060b7db | ||
|   | 0de64f1fc7 | ||
|   | f0508c0a90 | ||
|   | b51ae1dfaa | ||
|   | 6e7233d41b | ||
|   | 418041a56e | ||
|   | 17d20f5a18 | 
| @@ -116,7 +116,7 @@ Please see [Contribution guide](./CONTRIBUTING.md). | ||||
| <td><a href="https://www.patreon.com/user?u=12531784">Takashi Shibuya</a></td> | ||||
| </tr></table> | ||||
|  | ||||
| **Last updated:** Tue, 27 Nov 2018 06:24:05 UTC | ||||
| **Last updated:** Sat, 01 Dec 2018 22:05:05 UTC | ||||
| <!-- PATREON_END --> | ||||
|  | ||||
| :four_leaf_clover: Copyright | ||||
|   | ||||
| Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 94 KiB | 
| Before Width: | Height: | Size: 344 KiB After Width: | Height: | Size: 317 KiB | 
| Before Width: | Height: | Size: 125 KiB After Width: | Height: | Size: 95 KiB | 
| Before Width: | Height: | Size: 256 KiB After Width: | Height: | Size: 200 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/ai.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 243 KiB After Width: | Height: | Size: 235 KiB | 
| Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB | 
| Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 6.8 KiB | 
| Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB | 
| @@ -1,108 +1,17 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
| 
 | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="512" | ||||
|    height="512" | ||||
|    viewBox="0 0 135.46667 135.46667" | ||||
|    version="1.1" | ||||
|    id="svg8" | ||||
|    inkscape:version="0.92.1 r15371" | ||||
|    sodipodi:docname="favicon.svg" | ||||
|    inkscape:export-filename="C:\Users\syuilo\projects\misskey\assets\favicon\16.png" | ||||
|    inkscape:export-xdpi="3" | ||||
|    inkscape:export-ydpi="3"> | ||||
|    version="1.1" | ||||
|    viewBox="0 0 135.46667 135.46667" | ||||
|    height="512" | ||||
|    width="512"> | ||||
|   <defs | ||||
|      id="defs2"> | ||||
|     <inkscape:path-effect | ||||
|        effect="simplify" | ||||
|        id="path-effect5115" | ||||
|        is_visible="true" | ||||
|        steps="1" | ||||
|        threshold="0.000408163" | ||||
|        smooth_angles="360" | ||||
|        helper_size="0" | ||||
|        simplify_individual_paths="false" | ||||
|        simplify_just_coalesce="false" | ||||
|        simplifyindividualpaths="false" | ||||
|        simplifyJustCoalesce="false" /> | ||||
|     <inkscape:path-effect | ||||
|        effect="simplify" | ||||
|        id="path-effect5111" | ||||
|        is_visible="true" | ||||
|        steps="1" | ||||
|        threshold="0.000408163" | ||||
|        smooth_angles="360" | ||||
|        helper_size="0" | ||||
|        simplify_individual_paths="false" | ||||
|        simplify_just_coalesce="false" | ||||
|        simplifyindividualpaths="false" | ||||
|        simplifyJustCoalesce="false" /> | ||||
|     <inkscape:path-effect | ||||
|        effect="simplify" | ||||
|        id="path-effect5104" | ||||
|        is_visible="true" | ||||
|        steps="1" | ||||
|        threshold="0.000408163" | ||||
|        smooth_angles="360" | ||||
|        helper_size="0" | ||||
|        simplify_individual_paths="false" | ||||
|        simplify_just_coalesce="false" | ||||
|        simplifyindividualpaths="false" | ||||
|        simplifyJustCoalesce="false" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1.4142136" | ||||
|      inkscape:cx="15.466544" | ||||
|      inkscape:cy="235.92965" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="g4502" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="false" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:snap-center="true" | ||||
|      inkscape:snap-page="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1027" | ||||
|      inkscape:window-x="-8" | ||||
|      inkscape:window-y="1072" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-object-midpoints="true" | ||||
|      inkscape:snap-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      fit-margin-top="0" | ||||
|      fit-margin-left="0" | ||||
|      fit-margin-right="0" | ||||
|      fit-margin-bottom="0" | ||||
|      objecttolerance="1" | ||||
|      guidetolerance="1" | ||||
|      inkscape:snap-nodes="false" | ||||
|      inkscape:snap-others="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4504" | ||||
|        spacingx="4.2333334" | ||||
|        spacingy="4.2333334" | ||||
|        empcolor="#ff3fff" | ||||
|        empopacity="0.25098039" | ||||
|        empspacing="4" /> | ||||
|   </sodipodi:namedview> | ||||
|      id="defs2" /> | ||||
|   <metadata | ||||
|      id="metadata5"> | ||||
|     <rdf:RDF> | ||||
| @@ -116,32 +25,27 @@ | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="レイヤー 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(-30.809093,-111.78601)"> | ||||
|      style="fill:#2fa3bc;fill-opacity:1" | ||||
|      transform="translate(-30.809093,-111.78601)" | ||||
|      id="layer1"> | ||||
|     <g | ||||
|        id="g4502" | ||||
|        transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"> | ||||
|        style="fill:#2fa3bc;fill-opacity:1" | ||||
|        transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)" | ||||
|        id="g4502"> | ||||
|       <g | ||||
|          style="fill:#2fa1bb;fill-opacity:1" | ||||
|          id="g5125"> | ||||
|          id="g5125" | ||||
|          transform="translate(-1.3333333e-6,-1.3439941e-6)" | ||||
|          style="fill:#2fa3bc;fill-opacity:1"> | ||||
|         <g | ||||
|            transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)" | ||||
|            aria-label="Mi" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#2fa3bc;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            id="text4489" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#2fa1bb;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            aria-label="Mi"> | ||||
|            transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"> | ||||
|           <path | ||||
|              sodipodi:nodetypes="zccssscssccscczzzccsccsscscsccz" | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path5210" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa1bb;fill-opacity:1;stroke-width:0.28950602px" | ||||
|              d="m 75.196381,231.17126 c -5.855419,0.0202 -10.885068,-3.50766 -13.2572,-7.61584 -1.266603,-1.79454 -3.772419,-2.43291 -3.807919,0 v 11.2332 c 0,4.51309 -1.645397,8.41504 -4.936191,11.70583 -3.196772,3.19677 -7.098714,4.79516 -11.705826,4.79516 -4.513089,0 -8.415031,-1.59839 -11.705825,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -61.7729 c 0,-3.47884 0.987238,-6.6286 2.961715,-9.44928 2.068499,-2.91471 4.701135,-4.9362 7.897906,-6.06447 1.786431,-0.65816 3.666885,-0.98724 5.641362,-0.98724 5.077225,0 9.308247,1.97448 12.693064,5.92343 1.786431,1.97448 2.820681,3.00873 3.102749,3.10275 0,0 13.408119,16.21319 13.78421,16.49526 0.376091,0.28206 1.480789,2.43848 4.127113,2.43848 2.646324,0 3.89218,-2.15642 4.26827,-2.43848 0.376091,-0.28207 13.784088,-16.49526 13.784088,-16.49526 0.09402,0.094 1.081261,-0.94022 2.961715,-3.10275 3.478837,-3.94895 7.756866,-5.92343 12.834096,-5.92343 1.88045,0 3.76091,0.32908 5.64136,0.98724 3.19677,1.12827 5.7824,3.14976 7.75688,6.06447 2.06849,2.82068 3.10274,5.97044 3.10274,9.44928 v 61.7729 c 0,4.51309 -1.6454,8.41504 -4.93619,11.70583 -3.19677,3.19677 -7.09871,4.79516 -11.70582,4.79516 -4.51309,0 -8.41504,-1.59839 -11.705828,-4.79516 -3.196772,-3.29079 -4.795158,-7.19274 -4.795158,-11.70583 v -11.2332 c -0.277898,-3.06563 -2.987588,-1.13379 -3.948953,0 -2.538613,4.70114 -7.401781,7.59567 -13.2572,7.61584 z" /> | ||||
|           <path | ||||
|              inkscape:connector-curvature="0" | ||||
|              id="path5212" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa1bb;fill-opacity:1;stroke-width:0.28950602px" | ||||
|              d="m 145.83461,185.00361 q -5.92343,0 -10.15445,-4.08999 -4.08999,-4.23102 -4.08999,-10.15445 0,-5.92343 4.08999,-10.01342 4.23102,-4.23102 10.15445,-4.23102 5.92343,0 10.15445,4.23102 4.23102,4.08999 4.23102,10.01342 0,5.92343 -4.23102,10.15445 -4.23102,4.08999 -10.15445,4.08999 z m 0.14103,2.82068 q 5.92343,0 10.01342,4.23102 4.23102,4.23102 4.23102,10.15445 v 34.83541 q 0,5.92343 -4.23102,10.15445 -4.08999,4.08999 -10.01342,4.08999 -5.92343,0 -10.15445,-4.08999 -4.23102,-4.23102 -4.23102,-10.15445 v -34.83541 q 0,-5.92343 4.23102,-10.15445 4.23102,-4.23102 10.15445,-4.23102 z" /> | ||||
|              transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)" | ||||
|              d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#2fa3bc;fill-opacity:1;stroke-width:1.09609616px" /> | ||||
|         </g> | ||||
|       </g> | ||||
|     </g> | ||||
|   | ||||
| Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 4.1 KiB | 
| Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 1.5 KiB | 
| Before Width: | Height: | Size: 446 B After Width: | Height: | Size: 430 B | 
| Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.0 KiB | 
| Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB | 
| Before Width: | Height: | Size: 774 B After Width: | Height: | Size: 671 B | 
| Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1015 B | 
							
								
								
									
										129
									
								
								assets/mi.svg
									
									
									
									
									
								
							
							
						
						| @@ -1,108 +1,17 @@ | ||||
| <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||
| <!-- Created with Inkscape (http://www.inkscape.org/) --> | ||||
| 
 | ||||
| <svg | ||||
|    xmlns:dc="http://purl.org/dc/elements/1.1/" | ||||
|    xmlns:cc="http://creativecommons.org/ns#" | ||||
|    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
|    xmlns:svg="http://www.w3.org/2000/svg" | ||||
|    xmlns="http://www.w3.org/2000/svg" | ||||
|    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | ||||
|    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | ||||
|    width="512" | ||||
|    height="512" | ||||
|    viewBox="0 0 135.46667 135.46667" | ||||
|    version="1.1" | ||||
|    id="svg8" | ||||
|    inkscape:version="0.92.1 r15371" | ||||
|    sodipodi:docname="mi.svg" | ||||
|    inkscape:export-filename="C:\Users\syuilo\projects\misskey\assets\favicon\32.png" | ||||
|    inkscape:export-xdpi="6" | ||||
|    inkscape:export-ydpi="6"> | ||||
|    version="1.1" | ||||
|    viewBox="0 0 135.46667 135.46667" | ||||
|    height="512" | ||||
|    width="512"> | ||||
|   <defs | ||||
|      id="defs2"> | ||||
|     <inkscape:path-effect | ||||
|        effect="simplify" | ||||
|        id="path-effect5115" | ||||
|        is_visible="true" | ||||
|        steps="1" | ||||
|        threshold="0.000408163" | ||||
|        smooth_angles="360" | ||||
|        helper_size="0" | ||||
|        simplify_individual_paths="false" | ||||
|        simplify_just_coalesce="false" | ||||
|        simplifyindividualpaths="false" | ||||
|        simplifyJustCoalesce="false" /> | ||||
|     <inkscape:path-effect | ||||
|        effect="simplify" | ||||
|        id="path-effect5111" | ||||
|        is_visible="true" | ||||
|        steps="1" | ||||
|        threshold="0.000408163" | ||||
|        smooth_angles="360" | ||||
|        helper_size="0" | ||||
|        simplify_individual_paths="false" | ||||
|        simplify_just_coalesce="false" | ||||
|        simplifyindividualpaths="false" | ||||
|        simplifyJustCoalesce="false" /> | ||||
|     <inkscape:path-effect | ||||
|        effect="simplify" | ||||
|        id="path-effect5104" | ||||
|        is_visible="true" | ||||
|        steps="1" | ||||
|        threshold="0.000408163" | ||||
|        smooth_angles="360" | ||||
|        helper_size="0" | ||||
|        simplify_individual_paths="false" | ||||
|        simplify_just_coalesce="false" | ||||
|        simplifyindividualpaths="false" | ||||
|        simplifyJustCoalesce="false" /> | ||||
|   </defs> | ||||
|   <sodipodi:namedview | ||||
|      id="base" | ||||
|      pagecolor="#ffffff" | ||||
|      bordercolor="#666666" | ||||
|      borderopacity="1.0" | ||||
|      inkscape:pageopacity="0.0" | ||||
|      inkscape:pageshadow="2" | ||||
|      inkscape:zoom="1.4142136" | ||||
|      inkscape:cx="232.39583" | ||||
|      inkscape:cy="251.50613" | ||||
|      inkscape:document-units="px" | ||||
|      inkscape:current-layer="g4502" | ||||
|      showgrid="true" | ||||
|      units="px" | ||||
|      inkscape:snap-bbox="true" | ||||
|      inkscape:bbox-nodes="true" | ||||
|      inkscape:snap-bbox-edge-midpoints="false" | ||||
|      inkscape:snap-smooth-nodes="true" | ||||
|      inkscape:snap-center="true" | ||||
|      inkscape:snap-page="true" | ||||
|      inkscape:window-width="1920" | ||||
|      inkscape:window-height="1027" | ||||
|      inkscape:window-x="-8" | ||||
|      inkscape:window-y="1072" | ||||
|      inkscape:window-maximized="1" | ||||
|      inkscape:snap-object-midpoints="true" | ||||
|      inkscape:snap-midpoints="true" | ||||
|      inkscape:object-paths="true" | ||||
|      fit-margin-top="0" | ||||
|      fit-margin-left="0" | ||||
|      fit-margin-right="0" | ||||
|      fit-margin-bottom="0" | ||||
|      objecttolerance="1" | ||||
|      guidetolerance="1" | ||||
|      inkscape:snap-nodes="false" | ||||
|      inkscape:snap-others="false"> | ||||
|     <inkscape:grid | ||||
|        type="xygrid" | ||||
|        id="grid4504" | ||||
|        spacingx="4.2333334" | ||||
|        spacingy="4.2333334" | ||||
|        empcolor="#ff3fff" | ||||
|        empopacity="0.25098039" | ||||
|        empspacing="4" /> | ||||
|   </sodipodi:namedview> | ||||
|      id="defs2" /> | ||||
|   <metadata | ||||
|      id="metadata5"> | ||||
|     <rdf:RDF> | ||||
| @@ -111,32 +20,30 @@ | ||||
|         <dc:format>image/svg+xml</dc:format> | ||||
|         <dc:type | ||||
|            rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | ||||
|         <dc:title /> | ||||
|         <dc:title></dc:title> | ||||
|       </cc:Work> | ||||
|     </rdf:RDF> | ||||
|   </metadata> | ||||
|   <g | ||||
|      inkscape:label="レイヤー 1" | ||||
|      inkscape:groupmode="layer" | ||||
|      id="layer1" | ||||
|      transform="translate(-30.809093,-111.78601)"> | ||||
|      transform="translate(-30.809093,-111.78601)" | ||||
|      id="layer1"> | ||||
|     <g | ||||
|        id="g4502" | ||||
|        transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)"> | ||||
|        transform="matrix(1.096096,0,0,1.096096,-2.960633,-44.023579)" | ||||
|        id="g4502"> | ||||
|       <g | ||||
|          style="fill:#000000;fill-opacity:1" | ||||
|          id="g5125" | ||||
|          transform="translate(-1.3333333e-6,-1.3439941e-6)" | ||||
|          id="g5125"> | ||||
|          style="fill:#000000;fill-opacity:1"> | ||||
|         <g | ||||
|            transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)" | ||||
|            id="text4489" | ||||
|            aria-label="Mi" | ||||
|            style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:141.03404236px;line-height:476.69509888px;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.28950602px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" | ||||
|            aria-label="Mi"> | ||||
|            id="text4489" | ||||
|            transform="matrix(0.91391326,0,0,0.91391326,7.9719907,17.595761)"> | ||||
|           <path | ||||
|              style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#000000;fill-opacity:1;stroke-width:1.09609616px" | ||||
|              d="M 62.474609 76.585938 C 54.999059 76.585938 47.878825 77.832365 41.115234 80.324219 C 29.011968 84.595952 19.044417 92.249798 11.212891 103.28516 C 3.7373405 113.96451 0 125.88934 0 139.06055 L 0 372.93945 C 0 390.02642 6.0510264 404.79858 18.154297 417.25781 C 30.613543 429.36108 45.387643 435.41406 62.474609 435.41406 C 79.917556 435.41406 94.689698 429.36108 106.79297 417.25781 C 119.25222 404.79858 125.48242 390.02642 125.48242 372.93945 L 125.48242 330.4082 C 125.61683 321.19698 135.10492 323.61391 139.90039 330.4082 C 148.8815 345.96215 167.92265 359.32062 190.0918 359.24414 C 212.26095 359.16778 230.67374 348.20715 240.28516 330.4082 C 243.92497 326.11557 254.18418 318.80145 255.23633 330.4082 L 255.23633 372.93945 C 255.23633 390.02642 261.28735 404.79858 273.39062 417.25781 C 285.84985 429.36108 300.62397 435.41406 317.71094 435.41406 C 335.15388 435.41406 349.92603 429.36108 362.0293 417.25781 C 374.48853 404.79858 380.71875 390.02642 380.71875 372.93945 L 380.71875 139.06055 C 380.71875 125.88934 376.80415 113.96451 368.97266 103.28516 C 361.49709 92.249798 351.70678 84.595952 339.60352 80.324219 C 332.48396 77.832365 325.3637 76.585938 318.24414 76.585938 C 299.02128 76.585938 282.82549 84.062587 269.6543 99.013672 C 262.53473 107.20121 258.79542 111.11761 258.43945 110.76172 C 258.43945 110.76172 207.67587 172.14495 206.25195 173.21289 C 204.82804 174.2808 200.11102 182.44531 190.0918 182.44531 C 180.07257 182.44531 175.89071 174.2808 174.4668 173.21289 C 173.04288 172.14495 122.2793 110.76172 122.2793 110.76172 C 121.21136 110.40575 117.29484 106.48923 110.53125 99.013672 C 97.716024 84.062587 81.697447 76.585938 62.474609 76.585938 z M 457.53516 76.585938 C 442.58406 76.585937 429.7692 81.926117 419.08984 92.605469 C 408.76646 102.92885 403.60547 115.56648 403.60547 130.51758 C 403.60547 145.46868 408.76646 158.28354 419.08984 168.96289 C 429.7692 179.28627 442.58406 184.44922 457.53516 184.44922 C 472.48625 184.44922 485.30112 179.28627 495.98047 168.96289 C 506.65982 158.28354 512 145.46868 512 130.51758 C 512 115.56648 506.65982 102.92885 495.98047 92.605469 C 485.30112 81.926117 472.48625 76.585938 457.53516 76.585938 z M 458.06836 195.12695 C 443.11726 195.12695 430.3024 200.46713 419.62305 211.14648 C 408.94369 221.82584 403.60547 234.6407 403.60547 249.5918 L 403.60547 381.48242 C 403.60547 396.43352 408.94369 409.24838 419.62305 419.92773 C 430.3024 430.25112 443.11726 435.41406 458.06836 435.41406 C 473.01946 435.41406 485.65709 430.25112 495.98047 419.92773 C 506.65982 409.24838 512 396.43352 512 381.48242 L 512 249.5918 C 512 234.6407 506.65982 221.82584 495.98047 211.14648 C 485.65709 200.46713 473.01946 195.12695 458.06836 195.12695 z " | ||||
|              id="path5210" | ||||
|              transform="matrix(0.26412464,0,0,0.26412464,24.988264,136.28626)" | ||||
|              id="path5210" /> | ||||
|              d="m 62.474609,76.585938 c -7.47555,0 -14.595784,1.246427 -21.359375,3.738281 C 29.011968,84.595952 19.044417,92.249798 11.212891,103.28516 3.7373405,113.96451 0,125.88934 0,139.06055 v 233.8789 c 0,17.08697 6.0510264,31.85913 18.154297,44.31836 12.459246,12.10327 27.233346,18.15625 44.320312,18.15625 17.442947,0 32.215089,-6.05298 44.318361,-18.15625 12.45925,-12.45923 18.68945,-27.23139 18.68945,-44.31836 V 330.4082 c 0.13441,-9.21122 9.6225,-6.79429 14.41797,0 8.98111,15.55395 28.02226,28.91242 50.19141,28.83594 22.16915,-0.0764 40.58194,-11.03699 50.19336,-28.83594 3.63981,-4.29263 13.89902,-11.60675 14.95117,0 v 42.53125 c 0,17.08697 6.05102,31.85913 18.15429,44.31836 12.45923,12.10327 27.23335,18.15625 44.32032,18.15625 17.44294,0 32.21509,-6.05298 44.31836,-18.15625 12.45923,-12.45923 18.68945,-27.23139 18.68945,-44.31836 v -233.8789 c 0,-13.17121 -3.9146,-25.09604 -11.74609,-35.77539 -7.47557,-11.035362 -17.26588,-18.689208 -29.36914,-22.960941 -7.11956,-2.491854 -14.23982,-3.738281 -21.35938,-3.738281 -19.22286,0 -35.41865,7.476649 -48.58984,22.427734 l -63.40235,74.199218 c -1.42391,1.06791 -6.14093,9.23242 -16.16015,9.23242 -10.01923,0 -14.20109,-8.16451 -15.625,-9.23242 L 110.53125,99.013672 C 97.716024,84.062587 81.697447,76.585938 62.474609,76.585938 Z m 395.060551,0 c -14.9511,-10e-7 -27.76596,5.340179 -38.44532,16.019531 -10.32338,10.323381 -15.48437,22.961011 -15.48437,37.912111 0,14.9511 5.16099,27.76596 15.48437,38.44531 10.67936,10.32338 23.49422,15.48633 38.44532,15.48633 14.95109,0 27.76596,-5.16295 38.44531,-15.48633 C 506.65982,158.28354 512,145.46868 512,130.51758 512,115.56648 506.65982,102.92885 495.98047,92.605469 485.30112,81.926117 472.48625,76.585938 457.53516,76.585938 Z m 0.5332,118.541012 c -14.9511,0 -27.76596,5.34018 -38.44531,16.01953 -10.67936,10.67936 -16.01758,23.49422 -16.01758,38.44532 v 131.89062 c 0,14.9511 5.33822,27.76596 16.01758,38.44531 10.67935,10.32339 23.49421,15.48633 38.44531,15.48633 14.9511,0 27.58873,-5.16294 37.91211,-15.48633 C 506.65982,409.24838 512,396.43352 512,381.48242 V 249.5918 c 0,-14.9511 -5.34018,-27.76596 -16.01953,-38.44532 -10.32338,-10.67935 -22.96101,-16.01953 -37.91211,-16.01953 z" | ||||
|              style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'OTADESIGN Rounded';-inkscape-font-specification:'OTADESIGN Rounded';fill:#000000;fill-opacity:1;stroke-width:1.09609616px" /> | ||||
|         </g> | ||||
|       </g> | ||||
|     </g> | ||||
|   | ||||
| Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 4.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/title.png
									
									
									
									
									
								
							
							
						
						| Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB | 
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -268,7 +268,7 @@ common/views/components/theme.vue: | ||||
|   install: "Install" | ||||
|   installed: "\"{}\" has been installed" | ||||
|   create-a-theme: "Create a theme" | ||||
|   save-created-theme: "Save a theme" | ||||
|   save-created-theme: "Save theme" | ||||
|   primary-color: "Primary color" | ||||
|   secondary-color: "Secondary color" | ||||
|   text-color: "Text color" | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "Used to confirm email and password reset etc." | ||||
|   enable-email: "Enable email delivery" | ||||
|   email: "Email Address" | ||||
|   smtp-use-ssl: "Use SSL for SMTP server" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTP Host" | ||||
|   smtp-port: "SMTP Port" | ||||
|   smtp-user: "SMTP User" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1628,6 +1628,9 @@ mobile/views/pages/user.vue: | ||||
|   block: "ブロック" | ||||
|   unblock: "ブロック解除" | ||||
|   years-old: "{age}歳" | ||||
|   push-to-list: "リストに追加" | ||||
|   select-list: "リストを選択してください" | ||||
|   list-pushed: "{user}を{list}に追加しました" | ||||
|  | ||||
| mobile/views/pages/user/home.vue: | ||||
|   recent-notes: "最近の投稿" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -26,7 +26,7 @@ common: | ||||
|   close: "닫기" | ||||
|   do-not-copy-paste: "여기에 코드를 입력하거나 붙여넣지 마십시오. 계정이 무단으로 사용될 수 있습니다." | ||||
|   load-more: "더보기" | ||||
|   enter-password: "パスワードを入力してください" | ||||
|   enter-password: "비밀번호를 입력하여 주십시오" | ||||
|   got-it: "알겠습니다" | ||||
|   customization-tips: | ||||
|     title: "커스터마이징 도움말" | ||||
| @@ -124,7 +124,7 @@ common: | ||||
|   is-remote-user: "이 유저 정보는 복사본입니다." | ||||
|   is-remote-post: "이 글 정보는 복사본입니다." | ||||
|   view-on-remote: "정확한 정보 보기" | ||||
|   renoted-by: "{user}가 Renote" | ||||
|   renoted-by: "{user}이(가) Renote" | ||||
|   error: | ||||
|     title: '오류가 발생했습니다' | ||||
|     retry: '다시 시도' | ||||
| @@ -458,10 +458,10 @@ common/views/components/profile-editor.vue: | ||||
|   saved: "프로필을 저장하였습니다" | ||||
|   uploading: "업로드 중" | ||||
|   upload-failed: "업로드에 실패하였습니다" | ||||
|   email: "メール設定" | ||||
|   email-address: "メールアドレス" | ||||
|   email-verified: "メールアドレスが確認されました" | ||||
|   email-not-verified: "メールアドレスが確認されていません。メールボックスをご確認ください。" | ||||
|   email: "메일 설정" | ||||
|   email-address: "메일 주소" | ||||
|   email-verified: "매일 주소가 확인되었습니다" | ||||
|   email-not-verified: "메일 주소가 확인되지 않았습니다. 받은 편지함을 확인하여 주시기 바랍니다." | ||||
| common/views/widgets/broadcast.vue: | ||||
|   fetching: "확인중" | ||||
|   no-broadcasts: "공지사항이 없습니다" | ||||
| @@ -736,8 +736,8 @@ desktop/views/components/settings.vue: | ||||
|   note-visibility: "게시물의 공개 범위" | ||||
|   default-note-visibility: "기본 공개 범위" | ||||
|   remember-note-visibility: "글의 공개 범위를 기억하기" | ||||
|   web-search-engine: "ウェブ検索エンジン" | ||||
|   web-search-engine-desc: "例: https://www.google.com/?#q={{query}}" | ||||
|   web-search-engine: "웹 검색엔진" | ||||
|   web-search-engine-desc: "예: https://www.google.com/?#q={{query}}" | ||||
|   auto-popout: "창 자동 팝아웃" | ||||
|   auto-popout-desc: "창이 열릴 때 팝아웃 (브라우저 밖으로 분리) 이 가능한 경우 자동으로 팝아웃합니다. 이 설정은 브라우저에 저장됩니다." | ||||
|   advanced: "고급 설정" | ||||
| @@ -1004,15 +1004,16 @@ admin/views/instance.vue: | ||||
|   external-user-recommendation-engine-desc: "예: https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}" | ||||
|   external-user-recommendation-timeout: "타임 아웃" | ||||
|   external-user-recommendation-timeout-desc: "밀리초 (예: 300000)" | ||||
|   email-config: "メールサーバーの設定" | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   smtp-pass: "SMTPパスワード" | ||||
|   email-config: "메일 서버 설정" | ||||
|   email-config-info: "메일 주소 확인 혹은 암호 재설정에 사용 됩니다." | ||||
|   enable-email: "메일 발신 활성화" | ||||
|   email: "메일 주소" | ||||
|   smtp-secure: "SMTP 연결에 암시적으로 SSL/TLS를 사용" | ||||
|   smtp-secure-info: "STARTTLS를 사용 시 ON으로 합니다." | ||||
|   smtp-host: "SMTP 호스트" | ||||
|   smtp-port: "SMTP 포트" | ||||
|   smtp-user: "SMTP 사용자" | ||||
|   smtp-pass: "SMTP 비밀번호" | ||||
| admin/views/charts.vue: | ||||
|   title: "차트" | ||||
|   per-day: "1일마다" | ||||
| @@ -1387,8 +1388,8 @@ mobile/views/pages/settings.vue: | ||||
|   note-visibility: "게시물의 공개 범위" | ||||
|   default-note-visibility: "기본 공개 범위" | ||||
|   remember-note-visibility: "글의 공개 범위를 기억하기" | ||||
|   web-search-engine: "ウェブ検索エンジン" | ||||
|   web-search-engine-desc: "例: https://www.google.com/?#q={{query}}" | ||||
|   web-search-engine: "웹 검색엔진" | ||||
|   web-search-engine-desc: "예: https://www.google.com/?#q={{query}}" | ||||
|   disable-via-mobile: "작성하는 글에 \"모바일에서 작성함\" 을 붙이지 않음" | ||||
|   load-raw-images: "첨부 이미지를 고품질로 표시" | ||||
|   load-remote-media: "원격 서버의 미디어를 표시" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -16,7 +16,7 @@ common: | ||||
|     reaction-desc: "あなたの気持ちを伝える最も簡単な方法です。Misskeyは、他のユーザーの投稿に様々なリアクションを付けることができます。いちどMisskeyのリアクション機能を体験してしまうと、もう「いいね」の概念しか存在しないSNSには戻れなくなるかもしれません。" | ||||
|     ui: "Interfejs" | ||||
|     ui-desc: "どのようなUIが使いやすいかは人それぞれです。だから、Misskeyは自由度の高いUIを持っています。レイアウトやデザインを調整したり、カスタマイズ可能な様々なウィジェットを配置したりして、自分だけのホームを作ってください。" | ||||
|     drive: "ドライブ" | ||||
|     drive: "Dysk" | ||||
|     drive-desc: "以前投稿したことのある画像をまた投稿したくなったことはありませんか?もしくは、アップロードしたファイルをフォルダ分けして整理したくなったことはありませんか?Misskeyの根幹に組み込まれたドライブ機能によってそれらが解決します。ファイルの共有も簡単です。" | ||||
|     outro: "他にもMisskeyにしかない機能はまだまだあるので、ぜひあなた自身の目で確かめてください。Misskeyは分散型SNSなので、このインスタンスが気に入らなければ他のインスタンスを試すこともできます。それでは、GLHF!" | ||||
|   adblock: | ||||
| @@ -53,7 +53,7 @@ common: | ||||
|     years_ago: "{} lat temu" | ||||
|   month-and-day: "{month}-{day}" | ||||
|   trash: "Kosz" | ||||
|   drive: "ドライブ" | ||||
|   drive: "Dysk" | ||||
|   messaging: "トーク" | ||||
|   weekday-short: | ||||
|     sunday: "N" | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
| @@ -1008,7 +1008,8 @@ admin/views/instance.vue: | ||||
|   email-config-info: "メールアドレス確認やパスワードリセットの際に使われます。" | ||||
|   enable-email: "メール配信を有効にする" | ||||
|   email: "メールアドレス" | ||||
|   smtp-use-ssl: "SMTPサーバーはSSLを使用" | ||||
|   smtp-secure: "SMTP接続に暗黙的なSSL/TLSを使用する" | ||||
|   smtp-secure-info: "STARTTLS使用時はオフにします。" | ||||
|   smtp-host: "SMTPホスト" | ||||
|   smtp-port: "SMTPポート" | ||||
|   smtp-user: "SMTPユーザー" | ||||
|   | ||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						| @@ -1,8 +1,8 @@ | ||||
| { | ||||
| 	"name": "misskey", | ||||
| 	"author": "syuilo <i@syuilo.com>", | ||||
| 	"version": "10.59.2", | ||||
| 	"clientVersion": "2.0.12277", | ||||
| 	"version": "10.60.0", | ||||
| 	"clientVersion": "2.0.12331", | ||||
| 	"codename": "nighthike", | ||||
| 	"main": "./built/index.js", | ||||
| 	"private": true, | ||||
| @@ -35,7 +35,7 @@ | ||||
| 		"@types/deep-equal": "1.0.1", | ||||
| 		"@types/double-ended-queue": "2.1.0", | ||||
| 		"@types/elasticsearch": "5.0.28", | ||||
| 		"@types/file-type": "5.2.1", | ||||
| 		"@types/file-type": "5.2.2", | ||||
| 		"@types/gulp": "3.8.36", | ||||
| 		"@types/gulp-htmlmin": "1.3.32", | ||||
| 		"@types/gulp-mocha": "0.0.32", | ||||
| @@ -223,7 +223,7 @@ | ||||
| 		"vue-content-loading": "1.5.3", | ||||
| 		"vue-cropperjs": "2.2.2", | ||||
| 		"vue-i18n": "8.3.2", | ||||
| 		"vue-js-modal": "1.3.26", | ||||
| 		"vue-js-modal": "1.3.27", | ||||
| 		"vue-loader": "15.4.2", | ||||
| 		"vue-marquee-text-component": "1.1.0", | ||||
| 		"vue-router": "3.0.2", | ||||
| @@ -236,7 +236,7 @@ | ||||
| 		"vuex-persistedstate": "2.5.4", | ||||
| 		"web-push": "3.3.3", | ||||
| 		"webfinger.js": "2.7.0", | ||||
| 		"webpack": "4.26.0", | ||||
| 		"webpack": "4.26.1", | ||||
| 		"webpack-cli": "3.1.2", | ||||
| 		"websocket": "1.0.28", | ||||
| 		"ws": "6.1.2", | ||||
|   | ||||
| @@ -48,7 +48,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
|  | ||||
| 		remove(i) { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'warning', | ||||
| 				text: this.$t('_remove.are-you-sure').replace('$1', this.announcements.find((_, j) => j == i).title), | ||||
| 				showCancelButton: true | ||||
| @@ -56,7 +56,7 @@ export default Vue.extend({ | ||||
| 				if (!res) return; | ||||
| 				this.announcements = this.announcements.filter((_, j) => j !== i); | ||||
| 				this.save(true); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('_remove.removed') | ||||
| 				}); | ||||
| @@ -68,13 +68,13 @@ export default Vue.extend({ | ||||
| 				broadcasts: this.announcements | ||||
| 			}).then(() => { | ||||
| 				if (!silent) { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'success', | ||||
| 						text: this.$t('saved') | ||||
| 					}); | ||||
| 				} | ||||
| 			}).catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}); | ||||
|   | ||||
| @@ -75,13 +75,13 @@ export default Vue.extend({ | ||||
| 				url: this.url, | ||||
| 				aliases: this.aliases.split(' ').filter(x => x.length > 0) | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('add-emoji.added') | ||||
| 				}); | ||||
| 				this.fetchEmojis(); | ||||
| 			}).catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}); | ||||
| @@ -103,12 +103,12 @@ export default Vue.extend({ | ||||
| 				url: emoji.url, | ||||
| 				aliases: emoji.aliases.split(' ').filter(x => x.length > 0) | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('updated') | ||||
| 				}); | ||||
| 			}).catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}); | ||||
| @@ -116,7 +116,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
|  | ||||
| 		removeEmoji(emoji) { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'warning', | ||||
| 				text: this.$t('remove-emoji.are-you-sure').replace('$1', emoji.name), | ||||
| 				showCancelButton: true | ||||
| @@ -126,13 +126,13 @@ export default Vue.extend({ | ||||
| 				this.$root.api('admin/emoji/remove', { | ||||
| 					id: emoji.id | ||||
| 				}).then(() => { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'success', | ||||
| 						text: this.$t('remove-emoji.removed') | ||||
| 					}); | ||||
| 					this.fetchEmojis(); | ||||
| 				}).catch(e => { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'error', | ||||
| 						text: e | ||||
| 					}); | ||||
|   | ||||
| @@ -212,7 +212,7 @@ export default Vue.extend({ | ||||
| 			this.$root.api('admin/invite').then(x => { | ||||
| 				this.inviteCode = x.code; | ||||
| 			}).catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}); | ||||
| @@ -258,12 +258,12 @@ export default Vue.extend({ | ||||
| 				smtpUser: this.smtpUser, | ||||
| 				smtpPass: this.smtpPass | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('saved') | ||||
| 				}); | ||||
| 			}).catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e | ||||
| 				}); | ||||
|   | ||||
| @@ -34,14 +34,14 @@ export default Vue.extend({ | ||||
| 			const process = async () => { | ||||
| 				const user = await this.$root.api('users/show', parseAcct(this.username)); | ||||
| 				await this.$root.api('admin/moderators/add', { userId: user.id }); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('add-moderator.added') | ||||
| 				}); | ||||
| 			}; | ||||
|  | ||||
| 			await process().catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e.toString() | ||||
| 				}); | ||||
|   | ||||
| @@ -115,12 +115,12 @@ export default Vue.extend({ | ||||
| 				return await this.$root.api('users/show', this.target.startsWith('@') ? parseAcct(this.target) : { userId: this.target }); | ||||
| 			} catch (e) { | ||||
| 				if (e == 'user not found') { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'error', | ||||
| 						text: this.$t('user-not-found') | ||||
| 					}); | ||||
| 				} else { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'error', | ||||
| 						text: e.toString() | ||||
| 					}); | ||||
| @@ -138,7 +138,7 @@ export default Vue.extend({ | ||||
| 		async resetPassword() { | ||||
| 			const user = await this.fetchUser(); | ||||
| 			this.$root.api('admin/reset-password', { userId: user.id }).then(res => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('password-updated', { password: res.password }) | ||||
| 				}); | ||||
| @@ -151,14 +151,14 @@ export default Vue.extend({ | ||||
| 			const process = async () => { | ||||
| 				const user = await this.fetchUser(); | ||||
| 				await this.$root.api('admin/verify-user', { userId: user.id }); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('verified') | ||||
| 				}); | ||||
| 			}; | ||||
|  | ||||
| 			await process().catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e.toString() | ||||
| 				}); | ||||
| @@ -173,14 +173,14 @@ export default Vue.extend({ | ||||
| 			const process = async () => { | ||||
| 				const user = await this.fetchUser(); | ||||
| 				await this.$root.api('admin/unverify-user', { userId: user.id }); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('unverified') | ||||
| 				}); | ||||
| 			}; | ||||
|  | ||||
| 			await process().catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e.toString() | ||||
| 				}); | ||||
| @@ -195,14 +195,14 @@ export default Vue.extend({ | ||||
| 			const process = async () => { | ||||
| 				const user = await this.fetchUser(); | ||||
| 				await this.$root.api('admin/suspend-user', { userId: user.id }); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('suspended') | ||||
| 				}); | ||||
| 			}; | ||||
|  | ||||
| 			await process().catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e.toString() | ||||
| 				}); | ||||
| @@ -217,14 +217,14 @@ export default Vue.extend({ | ||||
| 			const process = async () => { | ||||
| 				const user = await this.fetchUser(); | ||||
| 				await this.$root.api('admin/unsuspend-user', { userId: user.id }); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					text: this.$t('unsuspended') | ||||
| 				}); | ||||
| 			}; | ||||
|  | ||||
| 			await process().catch(e => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: e.toString() | ||||
| 				}); | ||||
|   | ||||
| @@ -21,12 +21,12 @@ export default async function($root: any, force = false, silent = false) { | ||||
| 			console.error(e); | ||||
| 		} | ||||
|  | ||||
| 		if (!silent) { | ||||
| 			$root.alert({ | ||||
| 		/*if (!silent) { | ||||
| 			$root.dialog({ | ||||
| 				title: $root.$t('@.update-available-title'), | ||||
| 				text: $root.$t('@.update-available', { newer, current }) | ||||
| 			}); | ||||
| 		} | ||||
| 		}*/ | ||||
|  | ||||
| 		return newer; | ||||
| 	} else { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ export default ($root: any) => { | ||||
| 	require('fuckadblock'); | ||||
|  | ||||
| 	function adBlockDetected() { | ||||
| 		$root.alert({ | ||||
| 		$root.dialog({ | ||||
| 			title: $root.$t('@.adblock.detected'), | ||||
| 			text: $root.$t('@.adblock.warning') | ||||
| 		}); | ||||
|   | ||||
| @@ -142,7 +142,7 @@ export default (opts: Opts = {}) => ({ | ||||
| 			this.$root.api('notes/favorites/create', { | ||||
| 				noteId: this.appearNote.id | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					splash: true | ||||
| 				}); | ||||
|   | ||||
| @@ -187,7 +187,8 @@ export default Vue.extend({ | ||||
| 				} else { | ||||
| 					this.$root.api('users/search', { | ||||
| 						query: this.q, | ||||
| 						limit: 30 | ||||
| 						limit: 10, | ||||
| 						detail: false | ||||
| 					}).then(users => { | ||||
| 						this.users = users; | ||||
| 						this.fetching = false; | ||||
|   | ||||
| @@ -2,9 +2,12 @@ | ||||
| <div class="felqjxyj" :class="{ splash }"> | ||||
| 	<div class="bg" ref="bg" @click="onBgClick"></div> | ||||
| 	<div class="main" ref="main"> | ||||
| 		<div class="icon" :class="type"><fa :icon="icon"/></div> | ||||
| 		<div class="icon" v-if="type" :class="type"><fa :icon="icon"/></div> | ||||
| 		<header v-if="title" v-html="title"></header> | ||||
| 		<div class="body" v-if="text" v-html="text"></div> | ||||
| 		<ui-select v-if="select" v-model="selectedValue"> | ||||
| 			<option v-for="item in select.items" :value="item.value">{{ item.text }}</option> | ||||
| 		</ui-select> | ||||
| 		<ui-horizon-group no-grow class="buttons fit-bottom" v-if="!splash"> | ||||
| 			<ui-button @click="ok" primary autofocus>OK</ui-button> | ||||
| 			<ui-button @click="cancel" v-if="showCancelButton">Cancel</ui-button> | ||||
| @@ -33,6 +36,9 @@ export default Vue.extend({ | ||||
| 			type: String, | ||||
| 			required: false | ||||
| 		}, | ||||
| 		select: { | ||||
| 			required: false | ||||
| 		}, | ||||
| 		showCancelButton: { | ||||
| 			type: Boolean, | ||||
| 			default: false | ||||
| @@ -43,6 +49,12 @@ export default Vue.extend({ | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	data() { | ||||
| 		return { | ||||
| 			selectedValue: null | ||||
| 		}; | ||||
| 	}, | ||||
| 
 | ||||
| 	computed: { | ||||
| 		icon(): any { | ||||
| 			switch (this.type) { | ||||
| @@ -83,7 +95,8 @@ export default Vue.extend({ | ||||
| 
 | ||||
| 	methods: { | ||||
| 		ok() { | ||||
| 			this.$emit('ok'); | ||||
| 			const result = this.select ? this.selectedValue : true; | ||||
| 			this.$emit('ok', result); | ||||
| 			this.close(); | ||||
| 		}, | ||||
| 
 | ||||
| @@ -180,8 +193,11 @@ export default Vue.extend({ | ||||
| 				display block | ||||
| 				margin 0 auto | ||||
| 
 | ||||
| 			& + header | ||||
| 				margin-top 16px | ||||
| 
 | ||||
| 		> header | ||||
| 			margin 16px 0 8px 0 | ||||
| 			margin 0 0 8px 0 | ||||
| 			font-weight bold | ||||
| 			font-size 20px | ||||
| 
 | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="onchrpzrvnoruiaenfcqvccjfuupzzwv"> | ||||
| <div class="onchrpzrvnoruiaenfcqvccjfuupzzwv" :class="{ big: $root.isMobile }"> | ||||
| 	<div class="backdrop" ref="backdrop" @click="close"></div> | ||||
| 	<div class="popover" :class="{ hukidasi }" ref="popover"> | ||||
| 		<template v-for="item, i in items"> | ||||
| @@ -125,6 +125,11 @@ export default Vue.extend({ | ||||
|  | ||||
| 	position initial | ||||
|  | ||||
| 	&.big | ||||
| 		> .popover | ||||
| 			> button | ||||
| 				font-size 15px | ||||
|  | ||||
| 	> .backdrop | ||||
| 		position fixed | ||||
| 		top 0 | ||||
|   | ||||
| @@ -115,9 +115,11 @@ export default Vue.extend({ | ||||
| 			} | ||||
| 			this.$root.api('users/search', { | ||||
| 				query: this.q, | ||||
| 				max: 5 | ||||
| 				localOnly: true, | ||||
| 				limit: 10, | ||||
| 				detail: false | ||||
| 			}).then(users => { | ||||
| 				this.result = users; | ||||
| 				this.result = users.filter(user => user.id != this.$store.state.i.id); | ||||
| 			}); | ||||
| 		}, | ||||
| 		navigate(user) { | ||||
|   | ||||
| @@ -78,7 +78,7 @@ export default Vue.extend({ | ||||
| 			this.$root.api('i/pin', { | ||||
| 				noteId: this.note.id | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					splash: true | ||||
| 				}); | ||||
| @@ -95,7 +95,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
|  | ||||
| 		del() { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'warning', | ||||
| 				text: this.$t('delete-confirm'), | ||||
| 				showCancelButton: true | ||||
| @@ -114,7 +114,7 @@ export default Vue.extend({ | ||||
| 			this.$root.api('notes/favorites/create', { | ||||
| 				noteId: this.note.id | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					splash: true | ||||
| 				}); | ||||
| @@ -126,7 +126,7 @@ export default Vue.extend({ | ||||
| 			this.$root.api('notes/favorites/delete', { | ||||
| 				noteId: this.note.id | ||||
| 			}).then(() => { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					splash: true | ||||
| 				}); | ||||
|   | ||||
| @@ -25,7 +25,7 @@ export default Vue.extend({ | ||||
| 						type: 'password' | ||||
| 					}).then(newPassword2 => { | ||||
| 						if (newPassword !== newPassword2) { | ||||
| 							this.$root.alert({ | ||||
| 							this.$root.dialog({ | ||||
| 								title: null, | ||||
| 								text: this.$t('not-match') | ||||
| 							}); | ||||
|   | ||||
| @@ -213,7 +213,7 @@ export default Vue.extend({ | ||||
| 				this.$store.state.i.bannerUrl = i.bannerUrl; | ||||
|  | ||||
| 				if (notify) { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'success', | ||||
| 						text: this.$t('saved') | ||||
| 					}); | ||||
|   | ||||
| @@ -223,7 +223,7 @@ export default Vue.extend({ | ||||
| 			try { | ||||
| 				theme = JSON5.parse(code); | ||||
| 			} catch (e) { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: this.$t('invalid-theme') | ||||
| 				}); | ||||
| @@ -236,7 +236,7 @@ export default Vue.extend({ | ||||
| 			} | ||||
|  | ||||
| 			if (theme.id == null) { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'error', | ||||
| 					text: this.$t('invalid-theme') | ||||
| 				}); | ||||
| @@ -244,7 +244,7 @@ export default Vue.extend({ | ||||
| 			} | ||||
|  | ||||
| 			if (this.$store.state.device.themes.some(t => t.id == theme.id)) { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'info', | ||||
| 					text: this.$t('already-installed') | ||||
| 				}); | ||||
| @@ -256,7 +256,7 @@ export default Vue.extend({ | ||||
| 				key: 'themes', value: themes | ||||
| 			}); | ||||
|  | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'success', | ||||
| 				text: this.$t('installed').replace('{}', theme.name) | ||||
| 			}); | ||||
| @@ -269,7 +269,7 @@ export default Vue.extend({ | ||||
| 				key: 'themes', value: themes | ||||
| 			}); | ||||
|  | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'info', | ||||
| 				text: this.$t('uninstalled').replace('{}', theme.name) | ||||
| 			}); | ||||
| @@ -306,7 +306,7 @@ export default Vue.extend({ | ||||
| 			const theme = this.myTheme; | ||||
|  | ||||
| 			if (theme.name == null || theme.name.trim() == '') { | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'warning', | ||||
| 					text: this.$t('theme-name-required') | ||||
| 				}); | ||||
| @@ -320,7 +320,7 @@ export default Vue.extend({ | ||||
| 				key: 'themes', value: themes | ||||
| 			}); | ||||
|  | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'success', | ||||
| 				text: this.$t('saved') | ||||
| 			}); | ||||
|   | ||||
| @@ -8,7 +8,7 @@ export default ($root: any) => { | ||||
|  | ||||
| 		const regex = RegExp('\.(jpg|jpeg|png|gif|webp|bmp|tiff)$'); | ||||
| 		if (!regex.test(file.name) ) { | ||||
| 			$root.alert({ | ||||
| 			$root.dialog({ | ||||
| 				title: '%fa:info-circle% %i18n:desktop.invalid-filetype%', | ||||
| 				text: null | ||||
| 			}); | ||||
| @@ -87,7 +87,7 @@ export default ($root: any) => { | ||||
| 				value: i.avatarUrl | ||||
| 			}); | ||||
|  | ||||
| 			$root.alert({ | ||||
| 			$root.dialog({ | ||||
| 				title: '%fa:info-circle% %i18n:desktop.avatar-updated%', | ||||
| 				text: null | ||||
| 			}); | ||||
|   | ||||
| @@ -87,7 +87,7 @@ export default ($root: any) => { | ||||
| 				value: i.bannerUrl | ||||
| 			}); | ||||
|  | ||||
| 			$root.alert({ | ||||
| 			$root.dialog({ | ||||
| 				title: '%fa:info-circle% %i18n:desktop.banner-updated%', | ||||
| 				text: null | ||||
| 			}); | ||||
|   | ||||
| @@ -170,7 +170,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 		copyUrl() { | ||||
| 			copyToClipboard(this.file.url); | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				title: this.$t('contextmenu.copied'), | ||||
| 				text: this.$t('contextmenu.copied-url-to-clipboard') | ||||
| 			}); | ||||
|   | ||||
| @@ -155,7 +155,7 @@ export default Vue.extend({ | ||||
| 				}).catch(err => { | ||||
| 					switch (err) { | ||||
| 						case 'detected-circular-definition': | ||||
| 							this.$root.alert({ | ||||
| 							this.$root.dialog({ | ||||
| 								title: this.$t('unable-to-process'), | ||||
| 								text: this.$t('circular-reference-detected') | ||||
| 							}); | ||||
|   | ||||
| @@ -313,7 +313,7 @@ export default Vue.extend({ | ||||
| 				}).catch(err => { | ||||
| 					switch (err) { | ||||
| 						case 'detected-circular-definition': | ||||
| 							this.$root.alert({ | ||||
| 							this.$root.dialog({ | ||||
| 								title: this.$t('unable-to-process'), | ||||
| 								text: this.$t('circular-reference-detected') | ||||
| 							}); | ||||
| @@ -340,7 +340,7 @@ export default Vue.extend({ | ||||
| 					folderId: this.folder ? this.folder.id : undefined | ||||
| 				}); | ||||
|  | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					title: this.$t('url-upload-requested'), | ||||
| 					text: this.$t('may-take-time') | ||||
| 				}); | ||||
|   | ||||
| @@ -186,7 +186,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 	methods: { | ||||
| 		hint() { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				title: this.$t('@.customization-tips.title'), | ||||
| 				text: this.$t('@.customization-tips.paragraph') | ||||
| 			}); | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="uofhebxjdgksfmltszlxurtjnjjsvioh" v-if="video.isSensitive && hide" @click="hide = false"> | ||||
| <div class="uofhebxjdgksfmltszlxurtjnjjsvioh" v-if="video.isSensitive && hide && !$store.state.device.alwaysShowNsfw" @click="hide = false"> | ||||
| 	<div> | ||||
| 		<b><fa icon="exclamation-triangle"/> {{ $t('sensitive') }}</b> | ||||
| 		<span>{{ $t('click-to-show') }}</span> | ||||
|   | ||||
| @@ -39,7 +39,7 @@ | ||||
| 		</header> | ||||
| 		<div class="body"> | ||||
| 			<p v-if="appearNote.cw != null" class="cw"> | ||||
| 				<span class="text" v-if="appearNote.cw != ''">{{ appearNote.cw }}</span> | ||||
| 				<misskey-flavored-markdown v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" /> | ||||
| 				<mk-cw-button v-model="showContent"/> | ||||
| 			</p> | ||||
| 			<div class="content" v-show="appearNote.cw == null || showContent"> | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| 		<mk-note-header class="header" :note="note" :mini="true"/> | ||||
| 		<div class="body"> | ||||
| 			<p v-if="note.cw != null" class="cw"> | ||||
| 				<span class="text" v-if="note.cw != ''">{{ note.cw }}</span> | ||||
| 				<misskey-flavored-markdown v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$store.state.i" :custom-emojis="note.emojis" /> | ||||
| 				<mk-cw-button v-model="showContent"/> | ||||
| 			</p> | ||||
| 			<div class="content" v-show="note.cw == null || showContent"> | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| 		<mk-note-header class="header" :note="note"/> | ||||
| 		<div class="body"> | ||||
| 			<p v-if="note.cw != null" class="cw"> | ||||
| 				<span class="text" v-if="note.cw != ''">{{ note.cw }}</span> | ||||
| 				<misskey-flavored-markdown v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$store.state.i" :custom-emojis="note.emojis" /> | ||||
| 				<mk-cw-button v-model="showContent"/> | ||||
| 			</p> | ||||
| 			<div class="content" v-show="note.cw == null || showContent"> | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| 			<mk-note-header class="header" :note="appearNote" :mini="mini"/> | ||||
| 			<div class="body" v-if="appearNote.deletedAt == null"> | ||||
| 				<p v-if="appearNote.cw != null" class="cw"> | ||||
| 					<span class="text" v-if="appearNote.cw != ''">{{ appearNote.cw }}</span> | ||||
| 					<misskey-flavored-markdown v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" /> | ||||
| 					<mk-cw-button v-model="showContent"/> | ||||
| 				</p> | ||||
| 				<div class="content" v-show="appearNote.cw == null || showContent"> | ||||
|   | ||||
| @@ -20,7 +20,7 @@ | ||||
| 								<mk-reaction-icon :reaction="notification.reaction"/> | ||||
| 								<router-link :to="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</router-link> | ||||
| 							</p> | ||||
| 							<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 							<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> | ||||
| 								<fa icon="quote-left"/>{{ getNoteSummary(notification.note) }}<fa icon="quote-right"/> | ||||
| 							</router-link> | ||||
| 						</div> | ||||
| @@ -32,7 +32,7 @@ | ||||
| 							<p><fa icon="retweet"/> | ||||
| 								<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link> | ||||
| 							</p> | ||||
| 							<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 							<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note.renote)"> | ||||
| 								<fa icon="quote-left"/>{{ getNoteSummary(notification.note.renote) }}<fa icon="quote-right"/> | ||||
| 							</router-link> | ||||
| 						</div> | ||||
| @@ -44,7 +44,7 @@ | ||||
| 							<p><fa icon="quote-left"/> | ||||
| 								<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link> | ||||
| 							</p> | ||||
| 							<router-link class="note-preview" :to="notification.note | notePage">{{ getNoteSummary(notification.note) }}</router-link> | ||||
| 							<router-link class="note-preview" :to="notification.note | notePage" :title="getNoteSummary(notification.note)">{{ getNoteSummary(notification.note) }}</router-link> | ||||
| 						</div> | ||||
| 					</template> | ||||
|  | ||||
| @@ -72,7 +72,7 @@ | ||||
| 							<p><fa icon="reply"/> | ||||
| 								<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link> | ||||
| 							</p> | ||||
| 							<router-link class="note-preview" :to="notification.note | notePage">{{ getNoteSummary(notification.note) }}</router-link> | ||||
| 							<router-link class="note-preview" :to="notification.note | notePage" :title="getNoteSummary(notification.note)">{{ getNoteSummary(notification.note) }}</router-link> | ||||
| 						</div> | ||||
| 					</template> | ||||
|  | ||||
| @@ -82,7 +82,7 @@ | ||||
| 							<p><fa icon="at"/> | ||||
| 								<router-link :to="notification.note.user | userPage" v-user-preview="notification.note.userId">{{ notification.note.user | userName }}</router-link> | ||||
| 							</p> | ||||
| 							<a class="note-preview" :href="notification.note | notePage">{{ getNoteSummary(notification.note) }}</a> | ||||
| 							<a class="note-preview" :href="notification.note | notePage" :title="getNoteSummary(notification.note)">{{ getNoteSummary(notification.note) }}</a> | ||||
| 						</div> | ||||
| 					</template> | ||||
|  | ||||
| @@ -90,7 +90,7 @@ | ||||
| 						<mk-avatar class="avatar" :user="notification.user"/> | ||||
| 						<div class="text"> | ||||
| 							<p><fa icon="chart-pie"/><a :href="notification.user | userPage" v-user-preview="notification.user.id">{{ notification.user | userName }}</a></p> | ||||
| 							<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 							<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> | ||||
| 								<fa icon="quote-left"/>{{ getNoteSummary(notification.note) }}<fa icon="quote-right"/> | ||||
| 							</router-link> | ||||
| 						</div> | ||||
| @@ -219,7 +219,7 @@ export default Vue.extend({ | ||||
| 				margin 0 | ||||
| 				padding 16px | ||||
| 				overflow-wrap break-word | ||||
| 				font-size 13px | ||||
| 				font-size 12px | ||||
| 				border-bottom solid 1px var(--faceDivider) | ||||
|  | ||||
| 				&:last-child | ||||
| @@ -262,9 +262,18 @@ export default Vue.extend({ | ||||
|  | ||||
| 				.note-preview | ||||
| 					color var(--noteText) | ||||
| 					display inline-block | ||||
| 					overflow hidden | ||||
| 					max-height 48px | ||||
| 					word-break break-all | ||||
|  | ||||
| 				.note-ref | ||||
| 					color var(--noteText) | ||||
| 					display inline-block | ||||
| 					width: 100% | ||||
| 					overflow hidden | ||||
| 					white-space nowrap | ||||
| 					text-overflow ellipsis | ||||
|  | ||||
| 					[data-icon] | ||||
| 						font-size 1em | ||||
|   | ||||
| @@ -15,7 +15,7 @@ | ||||
| 			<a v-for="tag in recentHashtags.slice(0, 5)" @click="addTag(tag)" :title="$t('click-to-tagging')">#{{ tag }}</a> | ||||
| 		</div> | ||||
| 		<div class="local-only" v-if="this.localOnly == true">{{ $t('local-only-message') }}</div> | ||||
| 		<input v-show="useCw" v-model="cw" :placeholder="$t('annotations')"> | ||||
| 		<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="'cw'"> | ||||
| 		<div class="textarea"> | ||||
| 			<textarea :class="{ with: (files.length != 0 || poll) }" | ||||
| 				ref="text" v-model="text" :disabled="posting" | ||||
|   | ||||
| @@ -596,12 +596,12 @@ export default Vue.extend({ | ||||
| 				this.checkingForUpdate = false; | ||||
| 				this.latestVersion = newer; | ||||
| 				if (newer == null) { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						title: this.$t('no-updates'), | ||||
| 						text: this.$t('no-updates-desc') | ||||
| 					}); | ||||
| 				} else { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						title: this.$t('update-available'), | ||||
| 						text: this.$t('update-available-desc') | ||||
| 					}); | ||||
| @@ -610,7 +610,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
| 		clean() { | ||||
| 			localStorage.clear(); | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				title: this.$t('cache-cleared'), | ||||
| 				text: this.$t('cache-cleared-desc') | ||||
| 			}); | ||||
|   | ||||
| @@ -156,7 +156,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 	> .follow-button | ||||
| 		position absolute | ||||
| 		top 92px | ||||
| 		top 8px | ||||
| 		right 8px | ||||
|  | ||||
| </style> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| 				<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link> | ||||
| 				<mk-time :time="notification.createdAt"/> | ||||
| 			</header> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> | ||||
| 				<fa icon="quote-left"/>{{ getNoteSummary(notification.note) }} | ||||
| 				<fa icon="quote-right"/> | ||||
| 			</router-link> | ||||
| @@ -23,7 +23,7 @@ | ||||
| 				<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link> | ||||
| 				<mk-time :time="notification.createdAt"/> | ||||
| 			</header> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note.renote)"> | ||||
| 				<fa icon="quote-left"/>{{ getNoteSummary(notification.note.renote) }}<fa icon="quote-right"/> | ||||
| 			</router-link> | ||||
| 		</div> | ||||
| @@ -59,7 +59,7 @@ | ||||
| 				<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link> | ||||
| 				<mk-time :time="notification.createdAt"/> | ||||
| 			</header> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> | ||||
| 				<fa icon="quote-left"/>{{ getNoteSummary(notification.note) }}<fa icon="quote-right"/> | ||||
| 			</router-link> | ||||
| 		</div> | ||||
| @@ -112,7 +112,7 @@ export default Vue.extend({ | ||||
| .dsfykdcjpuwfvpefwufddclpjhzktmpw | ||||
| 	> .notification | ||||
| 		padding 16px | ||||
| 		font-size 13px | ||||
| 		font-size 12px | ||||
| 		overflow-wrap break-word | ||||
|  | ||||
| 		&:after | ||||
| @@ -150,6 +150,11 @@ export default Vue.extend({ | ||||
|  | ||||
| 			> .note-ref | ||||
| 				color var(--noteText) | ||||
| 				display inline-block | ||||
| 				width: 100% | ||||
| 				overflow hidden | ||||
| 				white-space nowrap | ||||
| 				text-overflow ellipsis | ||||
|  | ||||
| 				[data-icon] | ||||
| 					font-size 1em | ||||
|   | ||||
| @@ -307,7 +307,7 @@ export default Vue.extend({ | ||||
| 							listId: list.id, | ||||
| 							userId: this.user.id | ||||
| 						}); | ||||
| 						this.$root.alert({ | ||||
| 						this.$root.dialog({ | ||||
| 							type: 'success', | ||||
| 							splash: true | ||||
| 						}); | ||||
|   | ||||
| @@ -73,7 +73,7 @@ export default Vue.extend({ | ||||
| 		}, | ||||
|  | ||||
| 		block() { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'warning', | ||||
| 				text: this.$t('block-confirm'), | ||||
| 				showCancelButton: true | ||||
| @@ -108,9 +108,13 @@ export default Vue.extend({ | ||||
| 					listId: list.id, | ||||
| 					userId: this.user.id | ||||
| 				}); | ||||
| 				this.$root.alert({ | ||||
| 				this.$root.dialog({ | ||||
| 					type: 'success', | ||||
| 					title: 'Done!', | ||||
| 					text: this.$t('list-pushed').replace('{user}', this.user.name).replace('{list}', list.title) | ||||
| 					text: this.$t('list-pushed', { | ||||
| 						user: this.user.name, | ||||
| 						list: list.title | ||||
| 					}) | ||||
| 				}); | ||||
| 			}); | ||||
| 		} | ||||
|   | ||||
| @@ -15,7 +15,7 @@ import checkForUpdate from './common/scripts/check-for-update'; | ||||
| import MiOS from './mios'; | ||||
| import { clientVersion as version, codename, lang } from './config'; | ||||
| import { builtinThemes, lightTheme, applyTheme } from './theme'; | ||||
| import Alert from './common/views/components/alert.vue'; | ||||
| import Dialog from './common/views/components/dialog.vue'; | ||||
|  | ||||
| if (localStorage.getItem('theme') == null) { | ||||
| 	applyTheme(lightTheme); | ||||
| @@ -143,6 +143,9 @@ import { | ||||
| 	faCalendarAlt as farCalendarAlt, | ||||
| 	faHdd as farHdd, | ||||
| 	faMoon as farMoon, | ||||
| 	faPlayCircle as farPlayCircle, | ||||
| 	faLightbulb as farLightbulb, | ||||
| 	faStickyNote as farStickyNote, | ||||
| } from '@fortawesome/free-regular-svg-icons'; | ||||
|  | ||||
| import { | ||||
| @@ -248,7 +251,7 @@ library.add( | ||||
| 	faSync, | ||||
| 	faArrowLeft, | ||||
| 	faMapMarker, | ||||
|   faRobot, | ||||
| 	faRobot, | ||||
|  | ||||
| 	farBell, | ||||
| 	farEnvelope, | ||||
| @@ -268,6 +271,9 @@ library.add( | ||||
| 	farCalendarAlt, | ||||
| 	farHdd, | ||||
| 	farMoon, | ||||
| 	farPlayCircle, | ||||
| 	farLightbulb, | ||||
| 	farStickyNote, | ||||
|  | ||||
| 	fabTwitter, | ||||
| 	fabGithub, | ||||
| @@ -451,10 +457,10 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS]) => void, | ||||
| 						document.body.appendChild(x.$el); | ||||
| 						return x; | ||||
| 					}, | ||||
| 					alert(opts) { | ||||
| 					dialog(opts) { | ||||
| 						return new Promise((res) => { | ||||
| 							const vm = this.new(Alert, opts); | ||||
| 							vm.$once('ok', () => res(true)); | ||||
| 							const vm = this.new(Dialog, opts); | ||||
| 							vm.$once('ok', result => res(result)); | ||||
| 							vm.$once('cancel', () => res(false)); | ||||
| 						}); | ||||
| 					} | ||||
|   | ||||
| @@ -41,6 +41,12 @@ import FolderChooser from './views/components/drive-folder-chooser.vue'; | ||||
|  */ | ||||
| init((launch) => { | ||||
| 	Vue.mixin({ | ||||
| 		data() { | ||||
| 			return { | ||||
| 				isMobile: true | ||||
| 			}; | ||||
| 		}, | ||||
|  | ||||
| 		methods: { | ||||
| 			$post(opts) { | ||||
| 				const o = opts || {}; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
| <div class="icozogqfvdetwohsdglrbswgrejoxbdj" v-if="video.isSensitive && hide" @click="hide = false"> | ||||
| <div class="icozogqfvdetwohsdglrbswgrejoxbdj" v-if="video.isSensitive && hide && !$store.state.device.alwaysShowNsfw" @click="hide = false"> | ||||
| 	<div> | ||||
| 		<b><fa icon="exclamation-triangle"/> {{ $t('sensitive') }}</b> | ||||
| 		<span>{{ $t('click-to-show') }}</span> | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
| 		</header> | ||||
| 		<div class="body"> | ||||
| 			<p v-if="appearNote.cw != null" class="cw"> | ||||
| 				<span class="text" v-if="appearNote.cw != ''">{{ appearNote.cw }}</span> | ||||
| 				<misskey-flavored-markdown v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" /> | ||||
| 				<mk-cw-button v-model="showContent"/> | ||||
| 			</p> | ||||
| 			<div class="content" v-show="appearNote.cw == null || showContent"> | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| 		<mk-note-header class="header" :note="note" :mini="true"/> | ||||
| 		<div class="body"> | ||||
| 			<p v-if="note.cw != null" class="cw"> | ||||
| 				<span class="text" v-if="note.cw != ''">{{ note.cw }}</span> | ||||
| 				<misskey-flavored-markdown v-if="note.cw != ''" class="text" :text="note.cw" :author="note.user" :i="$store.state.i" :custom-emojis="note.emojis" /> | ||||
| 				<mk-cw-button v-model="showContent"/> | ||||
| 			</p> | ||||
| 			<div class="content" v-show="note.cw == null || showContent"> | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
| 			<mk-note-header class="header" :note="appearNote" :mini="true"/> | ||||
| 			<div class="body" v-if="appearNote.deletedAt == null"> | ||||
| 				<p v-if="appearNote.cw != null" class="cw"> | ||||
| 					<span class="text" v-if="appearNote.cw != ''">{{ appearNote.cw }}</span> | ||||
| 				<misskey-flavored-markdown v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" /> | ||||
| 					<mk-cw-button v-model="showContent"/> | ||||
| 				</p> | ||||
| 				<div class="content" v-show="appearNote.cw == null || showContent"> | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| 				<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link> | ||||
| 				<mk-time :time="notification.createdAt"/> | ||||
| 			</header> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> | ||||
| 				<fa icon="quote-left"/>{{ getNoteSummary(notification.note) }} | ||||
| 				<fa icon="quote-right"/> | ||||
| 			</router-link> | ||||
| @@ -23,7 +23,7 @@ | ||||
| 				<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link> | ||||
| 				<mk-time :time="notification.createdAt"/> | ||||
| 			</header> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note.renote)"> | ||||
| 				<fa icon="quote-left"/>{{ getNoteSummary(notification.note.renote) }}<fa icon="quote-right"/> | ||||
| 			</router-link> | ||||
| 		</div> | ||||
| @@ -59,7 +59,7 @@ | ||||
| 				<router-link :to="notification.user | userPage">{{ notification.user | userName }}</router-link> | ||||
| 				<mk-time :time="notification.createdAt"/> | ||||
| 			</header> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage"> | ||||
| 			<router-link class="note-ref" :to="notification.note | notePage" :title="getNoteSummary(notification.note)"> | ||||
| 				<fa icon="quote-left"/>{{ getNoteSummary(notification.note) }}<fa icon="quote-right"/> | ||||
| 			</router-link> | ||||
| 		</div> | ||||
| @@ -162,6 +162,11 @@ export default Vue.extend({ | ||||
|  | ||||
| 			> .note-ref | ||||
| 				color var(--noteText) | ||||
| 				display inline-block | ||||
| 				width: 100% | ||||
| 				overflow hidden | ||||
| 				white-space nowrap | ||||
| 				text-overflow ellipsis | ||||
|  | ||||
| 				[data-icon] | ||||
| 					font-size 1em | ||||
|   | ||||
| @@ -16,7 +16,7 @@ | ||||
| 				<span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span> | ||||
| 				<a @click="addVisibleUser">+{{ $t('add-visible-user') }}</a> | ||||
| 			</div> | ||||
| 			<input v-show="useCw" v-model="cw" :placeholder="$t('annotations')"> | ||||
| 			<input v-show="useCw" ref="cw" v-model="cw" :placeholder="$t('annotations')" v-autocomplete="'cw'"> | ||||
| 			<textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="'text'"></textarea> | ||||
| 			<div class="attaches" v-show="files.length != 0"> | ||||
| 				<x-draggable class="files" :list="files" :options="{ animation: 150 }"> | ||||
|   | ||||
| @@ -23,7 +23,7 @@ export default Vue.extend({ | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		fn() { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: 'warning', | ||||
| 				text: this.$t('read-all'), | ||||
| 				showCancelButton: true | ||||
|   | ||||
| @@ -402,12 +402,12 @@ export default Vue.extend({ | ||||
| 				this.checkingForUpdate = false; | ||||
| 				this.latestVersion = newer; | ||||
| 				if (newer == null) { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						title: this.$t('no-updates'), | ||||
| 						text: this.$t('no-updates-desc') | ||||
| 					}); | ||||
| 				} else { | ||||
| 					this.$root.alert({ | ||||
| 					this.$root.dialog({ | ||||
| 						title: this.$t('update-available'), | ||||
| 						text: this.$t('update-available-desc') | ||||
| 					}); | ||||
|   | ||||
| @@ -116,6 +116,34 @@ export default Vue.extend({ | ||||
|  | ||||
| 		menu() { | ||||
| 			let menu = [{ | ||||
| 				icon: ['fas', 'list'], | ||||
| 				text: this.$t('push-to-list'), | ||||
| 				action: async () => { | ||||
| 					const lists = await this.$root.api('users/lists/list'); | ||||
| 					const listId = await this.$root.dialog({ | ||||
| 						type: null, | ||||
| 						title: this.$t('select-list'), | ||||
| 						select: { | ||||
| 							items: lists.map(list => ({ | ||||
| 								value: list.id, text: list.title | ||||
| 							})) | ||||
| 						}, | ||||
| 						showCancelButton: true | ||||
| 					}); | ||||
| 					if (!listId) return; | ||||
| 					await this.$root.api('users/lists/push', { | ||||
| 						listId: listId, | ||||
| 						userId: this.user.id | ||||
| 					}); | ||||
| 					this.$root.dialog({ | ||||
| 						type: 'success', | ||||
| 						text: this.$t('list-pushed', { | ||||
| 							user: this.user.name, | ||||
| 							list: lists.find(l => l.id === listId).title | ||||
| 						}) | ||||
| 					}); | ||||
| 				} | ||||
| 			}, null, { | ||||
| 				icon: this.user.isMuted ? ['fas', 'eye'] : ['far', 'eye-slash'], | ||||
| 				text: this.user.isMuted ? this.$t('unmute') : this.$t('mute'), | ||||
| 				action: () => { | ||||
|   | ||||
| @@ -63,7 +63,7 @@ export default Vue.extend({ | ||||
|  | ||||
| 	methods: { | ||||
| 		showDialog() { | ||||
| 			this.$root.alert({ | ||||
| 			this.$root.dialog({ | ||||
| 				type: this.dialogType, | ||||
| 				title: this.dialogTitle, | ||||
| 				text: this.dialogText, | ||||
|   | ||||
| Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 274 KiB | 
| @@ -26,45 +26,6 @@ export default (source: string): Node[] => { | ||||
| 	nodes = concatText(nodes); | ||||
| 	concatTextRecursive(nodes); | ||||
|  | ||||
| 	function getBeforeTextNode(node: Node): Node { | ||||
| 		if (node == null) return null; | ||||
| 		if (node.name == 'text') return node; | ||||
| 		if (node.children) return getBeforeTextNode(node.children[node.children.length - 1]); | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	function getAfterTextNode(node: Node): Node { | ||||
| 		if (node == null) return null; | ||||
| 		if (node.name == 'text') return node; | ||||
| 		if (node.children) return getBeforeTextNode(node.children[0]); | ||||
| 		return null; | ||||
| 	} | ||||
|  | ||||
| 	function isBlockNode(node: Node): boolean { | ||||
| 		return ['blockCode', 'center', 'quote', 'title'].includes(node.name); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * ブロック要素の前後にある改行を削除します | ||||
| 	 * (ブロック要素自体が改行の役割を果たすため、余計に改行されてしまう) | ||||
| 	 * @param nodes | ||||
| 	 */ | ||||
| 	const removeNeedlessLineBreaks = (nodes: Node[]) => { | ||||
| 		nodes.forEach((node, i) => { | ||||
| 			if (node.children) removeNeedlessLineBreaks(node.children); | ||||
| 			if (isBlockNode(node)) { | ||||
| 				const before = getBeforeTextNode(nodes[i - 1]); | ||||
| 				const after = getAfterTextNode(nodes[i + 1]); | ||||
| 				if (before && before.props.text.endsWith('\n')) { | ||||
| 					before.props.text = before.props.text.substring(0, before.props.text.length - 1); | ||||
| 				} | ||||
| 				if (after && after.props.text.startsWith('\n')) { | ||||
| 					after.props.text = after.props.text.substring(1); | ||||
| 				} | ||||
| 			} | ||||
| 		}); | ||||
| 	}; | ||||
|  | ||||
| 	const removeEmptyTextNodes = (nodes: Node[]) => { | ||||
| 		nodes.forEach(n => { | ||||
| 			if (n.children) { | ||||
| @@ -74,8 +35,6 @@ export default (source: string): Node[] => { | ||||
| 		return nodes.filter(n => !(n.name == 'text' && n.props.text == '')); | ||||
| 	}; | ||||
|  | ||||
| 	removeNeedlessLineBreaks(nodes); | ||||
|  | ||||
| 	nodes = removeEmptyTextNodes(nodes); | ||||
|  | ||||
| 	return nodes; | ||||
|   | ||||
| @@ -162,7 +162,7 @@ const mfm = P.createLanguage({ | ||||
| 			let hashtag = match[1]; | ||||
| 			hashtag = hashtag.substr(0, getTrailingPosition(hashtag)); | ||||
| 			if (hashtag.match(/^[0-9]+$/)) return P.makeFailure(i, 'not a hashtag'); | ||||
| 			if (!['\n', ' ', ' ', '(', '「', null, undefined].includes(input[i - 1])) return P.makeFailure(i, 'require space before "#"'); | ||||
| 			if (input[i - 1] != null && input[i - 1].match(/[a-z0-9]/i)) return P.makeFailure(i, 'not a hashtag'); | ||||
| 			return P.makeSuccess(i + ('#' + hashtag).length, makeNode('hashtag', { hashtag: hashtag })); | ||||
| 		}), | ||||
| 	//#endregion | ||||
| @@ -254,7 +254,7 @@ const mfm = P.createLanguage({ | ||||
| 			const qInner = quote.join('\n').replace(/^>/gm, '').replace(/^ /gm, ''); | ||||
| 			if (qInner == '') return P.makeFailure(i, 'not a quote'); | ||||
| 			const contents = r.root.tryParse(qInner); | ||||
| 			return P.makeSuccess(i + quote.join('\n').length, makeNodeWithChildren('quote', contents)); | ||||
| 			return P.makeSuccess(i + quote.join('\n').length + 1, makeNodeWithChildren('quote', contents)); | ||||
| 		})), | ||||
| 	//#endregion | ||||
|  | ||||
|   | ||||
| @@ -29,18 +29,18 @@ const summarize = (note: any): string => { | ||||
| 	// 返信のとき | ||||
| 	if (note.replyId) { | ||||
| 		if (note.reply) { | ||||
| 			summary += ` RE: ${summarize(note.reply)}`; | ||||
| 			summary += `\n\nRE: ${summarize(note.reply)}`; | ||||
| 		} else { | ||||
| 			summary += ' RE: ...'; | ||||
| 			summary += '\n\nRE: ...'; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Renoteのとき | ||||
| 	if (note.renoteId) { | ||||
| 		if (note.renote) { | ||||
| 			summary += ` RN: ${summarize(note.renote)}`; | ||||
| 			summary += `\n\nRN: ${summarize(note.renote)}`; | ||||
| 		} else { | ||||
| 			summary += ' RN: ...'; | ||||
| 			summary += '\n\nRN: ...'; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -147,8 +147,8 @@ export const isRemoteUser = (user: any): user is IRemoteUser => | ||||
| 	!isLocalUser(user); | ||||
|  | ||||
| //#region Validators | ||||
| export function validateUsername(username: string): boolean { | ||||
| 	return typeof username == 'string' && /^[a-zA-Z0-9_]{1,20}$/.test(username); | ||||
| export function validateUsername(username: string, remote?: boolean): boolean { | ||||
| 	return typeof username == 'string' && (remote ? /^\w+([\w\.-]+\w+)?$/ : /^[a-zA-Z0-9_]{1,20}$/).test(username); | ||||
| } | ||||
|  | ||||
| export function validatePassword(password: string): boolean { | ||||
|   | ||||
| @@ -103,6 +103,8 @@ export async function createNote(value: any, resolver?: Resolver, silent = false | ||||
| 		quote = await resolveNote(note._misskey_quote).catch(() => null); | ||||
| 	} | ||||
|  | ||||
| 	const cw = note.summary === '' ? null : note.summary; | ||||
|  | ||||
| 	// テキストのパース | ||||
| 	const text = note._misskey_content ? note._misskey_content : htmlToMFM(note.content); | ||||
|  | ||||
| @@ -120,7 +122,7 @@ export async function createNote(value: any, resolver?: Resolver, silent = false | ||||
| 		files: files, | ||||
| 		reply, | ||||
| 		renote: quote, | ||||
| 		cw: note.summary, | ||||
| 		cw: cw, | ||||
| 		text: text, | ||||
| 		viaMobile: false, | ||||
| 		localOnly: false, | ||||
|   | ||||
| @@ -43,7 +43,7 @@ function validatePerson(x: any, uri: string) { | ||||
| 		return new Error('invalid person: inbox is not a string'); | ||||
| 	} | ||||
|  | ||||
| 	if (!validateUsername(x.preferredUsername)) { | ||||
| 	if (!validateUsername(x.preferredUsername, true)) { | ||||
| 		return new Error('invalid person: invalid username'); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -106,6 +106,8 @@ export default async function renderNote(note: INote, dive = true): Promise<any> | ||||
| 		text += `\n\nRE: ${url}`; | ||||
| 	} | ||||
|  | ||||
| 	const summary = note.cw === '' ? String.fromCharCode(0x200B) : note.cw; | ||||
|  | ||||
| 	const content = toHtml(Object.assign({}, note, { text })); | ||||
|  | ||||
| 	const emojis = await getEmojis(note.emojis); | ||||
| @@ -121,7 +123,7 @@ export default async function renderNote(note: INote, dive = true): Promise<any> | ||||
| 		id: `${config.url}/notes/${note._id}`, | ||||
| 		type: 'Note', | ||||
| 		attributedTo, | ||||
| 		summary: note.cw, | ||||
| 		summary, | ||||
| 		content, | ||||
| 		_misskey_content: text, | ||||
| 		_misskey_quote: quote, | ||||
|   | ||||
| @@ -78,6 +78,7 @@ export default define(meta, (ps) => new Promise(async (res, rej) => { | ||||
| 		_id: -1 | ||||
| 	}; | ||||
| 	const query = { | ||||
| 		deletedAt: null, | ||||
| 		visibility: 'public' | ||||
| 	} as any; | ||||
| 	if (ps.sinceId) { | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| const ms = require('ms'); | ||||
| import $ from 'cafy'; | ||||
| import User, { pack } from '../../../../models/user'; | ||||
| import User, { pack, ILocalUser } from '../../../../models/user'; | ||||
| import { getFriendIds } from '../../common/get-friends'; | ||||
| import Mute from '../../../../models/mute'; | ||||
| import * as request from 'request'; | ||||
| import * as request from 'request-promise-native'; | ||||
| import config from '../../../../config'; | ||||
| import define from '../../define'; | ||||
| import fetchMeta from '../../../../misc/fetch-meta'; | ||||
|  | ||||
| import resolveUser from '../../../../remote/resolve-user'; | ||||
|  | ||||
| export const meta = { | ||||
| 	desc: { | ||||
| @@ -54,13 +54,10 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { | ||||
| 			json: true, | ||||
| 			followRedirect: true, | ||||
| 			followAllRedirects: true | ||||
| 		}, (error: any, response: any, body: any) => { | ||||
| 			if (!error && response.statusCode == 200) { | ||||
| 				res(body); | ||||
| 			} else { | ||||
| 				res([]); | ||||
| 			} | ||||
| 		}); | ||||
| 		}) | ||||
| 			.then(body => convertUsers(body, me)) | ||||
| 			.then(packed => res(packed)) | ||||
| 			.catch(e => rej(e)); | ||||
| 	} else { | ||||
| 		// ID list of the user itself and other users who the user follows | ||||
| 		const followingIds = await getFriendIds(me._id); | ||||
| @@ -91,3 +88,30 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { | ||||
| 		res(await Promise.all(users.map(user => pack(user, me, { detail: true })))); | ||||
| 	} | ||||
| })); | ||||
|  | ||||
| type IRecommendUser = { | ||||
| 	name: string; | ||||
| 	username: string; | ||||
| 	host: string; | ||||
| 	description: string; | ||||
| 	avatarUrl: string; | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Resolve/Pack dummy users | ||||
|  */ | ||||
| async function convertUsers(src: IRecommendUser[], me: ILocalUser) { | ||||
| 	const packed = await Promise.all(src.map(async x => { | ||||
| 		const user = await resolveUser(x.username, x.host) | ||||
| 			.catch(() => { | ||||
| 				console.warn(`Can't resolve ${x.username}@${x.host}`); | ||||
| 				return null; | ||||
| 			}); | ||||
|  | ||||
| 		if (user == null) return x; | ||||
|  | ||||
| 		return await pack(user, me, { detail: true }); | ||||
| 	})); | ||||
|  | ||||
| 	return packed; | ||||
| } | ||||
|   | ||||
| @@ -41,11 +41,19 @@ export const meta = { | ||||
| 				'ja-JP': 'ローカルユーザーのみ検索対象にするか否か' | ||||
| 			} | ||||
| 		}, | ||||
|  | ||||
| 		detail: { | ||||
| 			validator: $.bool.optional, | ||||
| 			default: true, | ||||
| 			desc: { | ||||
| 				'ja-JP': '詳細なユーザー情報を含めるか否か' | ||||
| 			} | ||||
| 		}, | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| export default define(meta, (ps, me) => new Promise(async (res, rej) => { | ||||
| 	const isUsername = validateUsername(ps.query.replace('@', '')); | ||||
| 	const isUsername = validateUsername(ps.query.replace('@', ''), true); | ||||
|  | ||||
| 	let users: IUser[] = []; | ||||
|  | ||||
| @@ -72,6 +80,5 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Serialize | ||||
| 	res(await Promise.all(users.map(user => pack(user, me, { detail: true })))); | ||||
| 	res(await Promise.all(users.map(user => pack(user, me, { detail: ps.detail })))); | ||||
| })); | ||||
|   | ||||
| @@ -117,14 +117,14 @@ async function CreateRemoteInboxes(user: ILocalUser): Promise<string[]> { | ||||
|  | ||||
| 	const queue: string[] = []; | ||||
|  | ||||
| 	followers.map(following => { | ||||
| 	for (const following of followers) { | ||||
| 		const follower = following._follower; | ||||
|  | ||||
| 		if (isRemoteUser(follower)) { | ||||
| 			const inbox = follower.sharedInbox || follower.inbox; | ||||
| 			if (!queue.includes(inbox)) queue.push(inbox); | ||||
| 		} | ||||
| 	}); | ||||
| 	} | ||||
|  | ||||
| 	return queue; | ||||
| } | ||||
|   | ||||
| @@ -19,14 +19,14 @@ export async function publishToFollowers(userId: mongo.ObjectID) { | ||||
|  | ||||
| 	// フォロワーがリモートユーザーかつ投稿者がローカルユーザーならUpdateを配信 | ||||
| 	if (isLocalUser(user)) { | ||||
| 		followers.map(following => { | ||||
| 		for (const following of followers) { | ||||
| 			const follower = following._follower; | ||||
|  | ||||
| 			if (isRemoteUser(follower)) { | ||||
| 				const inbox = follower.sharedInbox || follower.inbox; | ||||
| 				if (!queue.includes(inbox)) queue.push(inbox); | ||||
| 			} | ||||
| 		}); | ||||
| 		} | ||||
|  | ||||
| 		if (queue.length > 0) { | ||||
| 			const content = packAp(renderUpdate(await renderPerson(user), user)); | ||||
|   | ||||
| @@ -155,12 +155,14 @@ export default async (user: IUser, data: Option, silent = false) => new Promise< | ||||
|  | ||||
| 	// Parse MFM | ||||
| 	const tokens = data.text ? parse(data.text) : []; | ||||
| 	const cwTokens = data.cw ? parse(data.cw) : []; | ||||
| 	const combinedTokens = tokens.concat(cwTokens); | ||||
|  | ||||
| 	const tags = extractHashtags(tokens); | ||||
| 	const tags = extractHashtags(combinedTokens); | ||||
|  | ||||
| 	const emojis = extractEmojis(tokens); | ||||
| 	const emojis = extractEmojis(combinedTokens); | ||||
|  | ||||
| 	const mentionedUsers = data.apMentions || await extractMentionedUsers(user, tokens); | ||||
| 	const mentionedUsers = data.apMentions || await extractMentionedUsers(user, combinedTokens); | ||||
|  | ||||
| 	if (data.reply && !user._id.equals(data.reply.userId) && !mentionedUsers.some(u => u._id.equals(data.reply.userId))) { | ||||
| 		mentionedUsers.push(await User.findOne({ _id: data.reply.userId })); | ||||
| @@ -201,7 +203,7 @@ export default async (user: IUser, data: Option, silent = false) => new Promise< | ||||
| 	} | ||||
|  | ||||
| 	// ハッシュタグ登録 | ||||
| 	tags.map(tag => registerHashtag(user, tag)); | ||||
| 	for (const tag of tags) registerHashtag(user, tag); | ||||
|  | ||||
| 	// ファイルが添付されていた場合ドライブのファイルの「このファイルが添付された投稿一覧」プロパティにこの投稿を追加 | ||||
| 	if (data.files) { | ||||
| @@ -562,7 +564,7 @@ async function publishToFollowers(note: INote, user: IUser, noteActivity: any) { | ||||
|  | ||||
| 	const queue: string[] = []; | ||||
|  | ||||
| 	followers.map(following => { | ||||
| 	for (const following of followers) { | ||||
| 		const follower = following._follower; | ||||
|  | ||||
| 		if (isLocalUser(follower)) { | ||||
| @@ -586,7 +588,7 @@ async function publishToFollowers(note: INote, user: IUser, noteActivity: any) { | ||||
| 				if (!queue.includes(inbox)) queue.push(inbox); | ||||
| 			} | ||||
| 		} | ||||
| 	}); | ||||
| 	} | ||||
|  | ||||
| 	queue.forEach(inbox => { | ||||
| 		deliver(user as any, noteActivity, inbox); | ||||
|   | ||||
							
								
								
									
										33
									
								
								test/mfm.ts
									
									
									
									
									
								
							
							
						
						| @@ -187,9 +187,9 @@ describe('Text', () => { | ||||
| 			}); | ||||
|  | ||||
| 			it('with text (zenkaku)', () => { | ||||
| 				const tokens = analyze('こんにちは #世界'); | ||||
| 				const tokens = analyze('こんにちは#世界'); | ||||
| 				assert.deepEqual([ | ||||
| 					text('こんにちは '), | ||||
| 					text('こんにちは'), | ||||
| 					node('hashtag', { hashtag: '世界' }) | ||||
| 				], tokens); | ||||
| 			}); | ||||
| @@ -299,6 +299,7 @@ describe('Text', () => { | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('foo') | ||||
| 					]), | ||||
| 					text('\n'), | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('bar') | ||||
| 					]), | ||||
| @@ -358,7 +359,7 @@ describe('Text', () => { | ||||
| 			it('with before and after texts', () => { | ||||
| 				const tokens = analyze('before\n> foo\nafter'); | ||||
| 				assert.deepEqual([ | ||||
| 					text('before'), | ||||
| 					text('before\n'), | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('foo') | ||||
| 					]), | ||||
| @@ -366,6 +367,24 @@ describe('Text', () => { | ||||
| 				], tokens); | ||||
| 			}); | ||||
|  | ||||
| 			it('multiple quotes', () => { | ||||
| 				const tokens = analyze('> foo\nbar\n\n> foo\nbar\n\n> foo\nbar'); | ||||
| 				assert.deepEqual([ | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('foo') | ||||
| 					]), | ||||
| 					text('bar\n\n'), | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('foo') | ||||
| 					]), | ||||
| 					text('bar\n\n'), | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('foo') | ||||
| 					]), | ||||
| 					text('bar'), | ||||
| 				], tokens); | ||||
| 			}); | ||||
|  | ||||
| 			it('require line break before ">"', () => { | ||||
| 				const tokens = analyze('foo>bar'); | ||||
| 				assert.deepEqual([ | ||||
| @@ -388,11 +407,11 @@ describe('Text', () => { | ||||
| 			it('trim line breaks', () => { | ||||
| 				const tokens = analyze('foo\n\n>a\n>>b\n>>\n>>>\n>>>c\n>>>\n>d\n\n'); | ||||
| 				assert.deepEqual([ | ||||
| 					text('foo\n'), | ||||
| 					text('foo\n\n'), | ||||
| 					nodeWithChildren('quote', [ | ||||
| 						text('a'), | ||||
| 						text('a\n'), | ||||
| 						nodeWithChildren('quote', [ | ||||
| 							text('b\n'), | ||||
| 							text('b\n\n'), | ||||
| 							nodeWithChildren('quote', [ | ||||
| 								text('\nc\n') | ||||
| 							]) | ||||
| @@ -664,7 +683,7 @@ describe('Text', () => { | ||||
| 			it('with before and after texts', () => { | ||||
| 				const tokens = analyze('before\n【foo】\nafter'); | ||||
| 				assert.deepEqual([ | ||||
| 					text('before'), | ||||
| 					text('before\n'), | ||||
| 					nodeWithChildren('title', [ | ||||
| 						text('foo') | ||||
| 					]), | ||||
|   | ||||